How to build google test with hidden visibility - cmake

When I build unit tests for a library (which is built with hidden visibility), I encounter about 400 warnings of this format:
direct access in function 'testing::internal::SuiteApiResolver<MyTestSuite>::GetTearDownCaseOrSuite(char const*, int)' from file 'libgtestd.a(gtest-all.o)' to global weak symbol 'testing::Test::TearDownTestSuite()' from file 'test_filemame.o' means the weak symbol cannot be overridden at runtime. This was likely caused by different translation units being compiled with different visibility settings.
By changing the googletest's option gtest_hide_internal_symbols from OFF to ON, the number of warnings greatly decrease. However, I still have some warnings of this type:
direct access in function 'testing::internal::SuiteApiResolver<testing::internal::(anonymous namespace)::FailureTest>::GetTearDownCaseOrSuite(char const*, int)' from file 'libgtestd.a(gtest-all.o)' to global weak symbol 'testing::Test::TearDownTestCase()' from file 'test_mytest.o' means the weak symbol cannot be overridden at runtime. This was likely caused by different translation units being compiled with different visibility settings.
Can someone explain why the warnings still exist, when I already turn on gtest_hide_internal_symbols option? What am I missing?

I'm not sure about GTest, but I have seen these warnings from LD.
You probably receive all of these warnings for sub-modules or dependencies, wherein gtest_hide_internal_symbols is not turned on.
My guess is that gtest_hide_internal_symbols controls the GCC/LLVM option -fvisiblility. Specifically, turning gtest_hide_internal_symbols to ON probably sets -fvisibility=hidden.
UPDATE:
My assumption was correct.
See https://github.com/google/googletest/blob/830fb567285c63ab5b5873e2e8b02f2249864916/googletest/CMakeLists.txt#L80.
if (gtest_hide_internal_symbols)
set(CMAKE_CXX_VISIBILITY_PRESET hidden)
set(CMAKE_VISIBILITY_INLINES_HIDDEN 1)
endif()
CMAKE_CXX_VISIBILITY_PRESET specifies -fvisibility and CMAKE_VISIBILITY_INLINES_HIDDEN specifies -fvisibility-inlines-hidden.

Related

In CMake, is there a way to set properties on all target dependencies?

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

Can not build thisJoinPoint lazily for this advice since it has no suitable guard

What is a "suitable guard" and what does it look like?
Linked this question because it refers to the same compiler message and the answer mentions a guard but not how to create one. Looked through the AspectJ docs but did not find and answer there.
This Lint warning is usually switched off in AJDT (AspectJ Development Tools) within Eclipse, but you can activate it as a warning or even error like this (I had to do it to actually see it at all when trying to reproduce your issue):
You can just ignore the Lint warning because basically it only says that there is no way for certain pointcuts to populate the thisJoinPoint object lazily during runtime because the pointcut has no dynamic component like if(), cflow() or similar, which is actually good news because it means that all your joinpoints can be determined statically during compile/weave time and are thus faster than dynamic pointcuts. On the other hand, the warning says that the tjp object always has to be created because for some reason it is also always needed during runtime and thus cannot be instantiated lazily.

How to instruct linker to consider strong IRQ definition present in static library insteadof weak definition

We have problem in linking strong USB_IRQ handler.
We have real USB IRQ definition present in a static library.
We are filling .vector table in application startup file (*.s) with handler name and we also have the __weak definition, defined in the same startup file.
While linking we see linker always picks-up weak IRQ definition present in the startup file instead of strong IRQ definition present in the library (*.a).
If we remove weak definition from startup file, the strong definition is considered and it works well.
The problem that we see is, the library file that contains strong definition is not referred in any means from our application, that means, we are not using any functions or structures present in that file. only, IRQ handler is used and that too it trigger only when there is a hardware event.
We use ARM GNU tool chain, tried multiple options nothing helps.
We went through the internet help, and found few options like, --no_remove and --keep linker options, but, these flags does not seems to be supported.
Please suggest if you have some input in this regard.
I think you need to make sure that at least one symbol in the same source file as the strong definition gets referenced from your program. Otherwise, the linker will have no reason to load the object file that contains the IRQ. So for example you could define some init function in that source file, and call it from your program.
Make sure the IRQ function is declared with __attribute__((used)) as well.

Can simply importing a header ever lead to run-time issues?

I realize that doing this can lead to compile errors. But is an import always safe if no (new) compile errors or warnings arise? If I use an import statement (e.g. to remove duplicate protocol definition warning), could doing so, on it's own, ever change the run-time behavior? What checks (if any) are necessary to ensure invariability of operation after a new header import?
Yes, importing a header can lead to run-time issues.
For example, you may get a warning that a selector is unknown so the compiler is making assumptions about its signature. If you fix that warning by importing the relevant header, then that changes the code the compiler is emitting. Generally, it would change the code from broken to correct, but that nevertheless results in a run-time change.
If you use #import, then the header could define preprocessor macros that radically alter the subsequent code. For example, it could #define setNeedsDisplay setHidden or something.
The only way I can think of to verify that importing the header didn't alter the generated code is to examine the generated code and compare before and after. You can ask Xcode or clang to produce assembly from the compilation. You could also use otool -tV to disassemble the binaries (although that wouldn't show changes in, say, static data like strings).

Can VB.NET-specific warnings be suppressed by <SupressMessage>?

I would like to suppress some of these VB.NET warnings at class level. (=Not globally.) Supression is intended as temporary woarkaround until the code of some classes gets properly cleaned. There are hundreds of ID: 42016 (Option Strict On disallows implicit conversions from 'TypeA' to 'TypeB'.) warnings in legacy code, I cannot afford to fix them all right now.
I found that SuppressMessage attribute can be effectively used for the task but I cannot find proper argument values to supply to <SuppressMessage()> for warning 42016.
My question is: can be warning 42016 and other above referenced VB.NET-specific warnings suppressed by SuppressMessage attribute?
If you know there is no way of doing it, I will accept it as the answer, too.
Note: I know how to suppress them globally, this is not an option at the moment.
No, that does not get you anywhere. SuppressMessageAttribute is only used by code analysis (aka FxCop), the VB.NET compiler ignores it. And it is not a warning, it is a compile error. You can never ignore an error.
Option Strict can only be changed at file scope, there is no support for changing it on-the-fly. The only reasonable approach here is to tackle the borken source code one .vb file at a time. Not an unreasonable approach.