Is there a per target set() method in modern CMake? - cmake

I'm trying to achieve the same behavior as set() function in CMake but using targets. Let's assume I have one main CMakeList and two sub-folders with one CMakeList each.
Foo CMakeLists.txt :
cmake_minimum_required(VERSION 3.8)
add_subdirectory(Bar)
add_subdirectory(Tox)
add_library(foo STATIC main.cpp)
#command to set UseFeatureA=ON
target_link_libraries(foo PUBLIC bar )
target_link_libraries(foo PUBLIC tox)
Bar CMakeLists.txt:
add_library(bar PUBLIC bar.cpp)
if(UseFeatureA) #This has to be true
target_sources(bar PRIVATE coolFeatureA.cpp)
endif()
Tox CMakeLists.txt:
add_library(tox STATIC tox.cpp)
if(UseFeatureA) #This has to be FALSE
target_sources(bar PRIVATE coolFeatureA.cpp)
endif()
I have tried target_compile_definition() in Foo but I don't know how to retrieve the var in Bar.
What am I doing wrong?

Related

CMake multiline generator expressions

How can I use multiline generator expressions? For example transforming this:
target_include_directories(application-smth
PRIVATE
$<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/data>
$<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/include/application-smth>
PUBLIC
$<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/include>
)
to this
target_include_directories(application-smth
PRIVATE
$<BUILD_INTERFACE:
${CMAKE_CURRENT_SOURCE_DIR}/data>
${CMAKE_CURRENT_SOURCE_DIR}/include/application-smth>
>
PUBLIC
$<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/include>
)
makes /include/application-smth folder headers not available

Clone library with different type

In my project we create every library as a module-library and install these.
Therefore we cannot link against these library-target in our unit-test.
add_library(foo MODULE foo.h foo.cpp)
target_link_libraries(foo PUBLIC bar::bar)
install(TARGET foo DESTINATION bin)
target_include_directories(foo PUBLIC ${CMAKE_CURRENT_SOURCE_DIR})
add_executable(foo_tester fooTester.cpp)
target_link_libraries(foo_tester foo) #not possible. foo is a module
add_test(NAME foo_tester COMMAND foo_tester)
My idea was to clone the library with a different type. But this seems very error-prone
function(cloneLibrary TARGET)
get_target_property(desired_sources ${TARGET} SOURCES)
get_target_property(desired_source_dir ${TARGET} SOURCE_DIR)
get_target_property(desired_include_dir ${TARGET} INCLUDE_DIRECTORIES)
get_target_property(desired_link_libraries ${TARGET} LINK_LIBRARIES)
get_target_property(desired_name ${TARGET} NAME)
set(obj_name ${desired_name}_objLib)
add_library(${obj_name} OBJECT ${desired_sources})
target_link_libraries(${obj_name} PUBLIC ${desired_link_libraries})
target_include_directories(${obj_name} PUBLIC ${desired_source_dir} ${desired_source_dir}})
endfunction(cloneLibrary)
Is there an easier mode? Any cmake-module?

Proguard obfuscationdictionary not working

What I'm trying to achieve is to avoid my method paramaters having the names like String paramString or int paramInt. I am trying to use -obfuscationdictionary but it's not working (at least it's not doing what I presume it should, which is use my dictionary words instead of paramString etc)
I have the following Proguard config files in place, but my list of dictionary words are not being used. (I checked that it is finding the dictionary file by renaming the file it looks for, and it didn't compile, stating it couldn't find my dictionary).
# ==========================
# ===== GENERIC CONFIG =====
# ==========================
# Logging
-verbose
# Java Runtime
-libraryjars <java.home>/lib/rt.jar
# don't think I use this
# Preserve native methods
-keepclasseswithmembernames,includedescriptorclasses class * {
native <methods>;
}
# don't think I use this
# Preserve special enum methods
-keepclassmembers,allowoptimization enum * {
public static **[] values();
public static ** valueOf(java.lang.String);
}
# Preserve some source so it can be retraced
-renamesourcefileattribute SourceFile
-keepattributes SourceFile,LineNumberTable,!LocalVariableTable,!LocalVariableTypeTable
# Specific config
-useuniqueclassmembernames
-dontusemixedcaseclassnames # think this is only for unpacking on Windows machines, so shouldn't be applicable
-repackageclasses
#-dontshrink
#-dontoptimize
-obfuscationdictionary proguardDictionary.txt
# ==============================
# ===== APPLICATION CONFIG =====
# ==============================
# Preserve application entry point
#-keep public class MY.MAIN.CLASS.PACKAGE.MyGame {
# public static void main(java.lang.String[]);
#}
# Only obfuscate proprietary code
#-keep class !MY.GAME.PACKAGE.HERE.** { *; }
# This is a configuration file for ProGuard.
# http://proguard.sourceforge.net/index.html#manual/usage.html
#
# Starting with version 2.2 of the Android plugin for Gradle, this file is distributed together with
# the plugin and unpacked at build-time. The files in $ANDROID_HOME are no longer maintained and
# will be ignored by new version of the Android plugin for Gradle.
# Optimizations: If you don't want to optimize, use the proguard-android.txt configuration file
# instead of this one, which turns off the optimization flags.
# Adding optimization introduces certain risks, since for example not all optimizations performed by
# ProGuard works on all versions of Dalvik. The following flags turn off various optimizations
# known to have issues, but the list may not be complete or up to date. (The "arithmetic"
# optimization can be used if you are only targeting Android 2.0 or later.) Make sure you test
# thoroughly if you go this route.
-optimizations !code/simplification/arithmetic,!code/simplification/cast,!field/*,!class/merging/*
-optimizationpasses 5
-allowaccessmodification
-dontusemixedcaseclassnames
-dontskipnonpubliclibraryclasses
-verbose
# Preserve some attributes that may be required for reflection.
-keepattributes *Annotation*,Signature,InnerClasses,EnclosingMethod
#-keep public class com.google.vending.licensing.ILicensingService
#-keep public class com.android.vending.licensing.ILicensingService
#-keep public class uk.co.russellwheeler.matcg.android.dfgcvb.ILicensingService
#-dontnote com.android.vending.licensing.ILicensingService
#-dontnote com.google.vending.licensing.ILicensingService
#-dontnote uk.co.russellwheeler.matcg.android.dfgcvb.ILicensingService
# For native methods, see http://proguard.sourceforge.net/manual/examples.html#native
-keepclasseswithmembernames class * {
native <methods>;
}
# Keep setters in Views so that animations can still work.
-keepclassmembers public class * extends android.view.View {
void set*(***);
*** get*();
}
# We want to keep methods in Activity that could be used in the XML attribute onClick.
-keepclassmembers class * extends android.app.Activity {
public void *(android.view.View);
}
# For enumeration classes, see http://proguard.sourceforge.net/manual/examples.html#enumerations
-keepclassmembers enum * {
public static **[] values();
public static ** valueOf(java.lang.String);
}
-keepclassmembers class * implements android.os.Parcelable {
public static final ** CREATOR;
}
-keepclassmembers class **.R$* {
public static <fields>;
}
# Preserve annotated Javascript interface methods.
-keepclassmembers class * {
#android.webkit.JavascriptInterface <methods>;
}
# The support libraries contains references to newer platform versions.
# Don't warn about those in case this app is linking against an older
# platform version. We know about them, and they are safe.
-dontnote android.support.**
-dontwarn android.support.**
# Understand the #Keep support annotation.
-keep class android.support.annotation.Keep
-keep #android.support.annotation.Keep class * {*;}
-keepclasseswithmembers class * {
#android.support.annotation.Keep <methods>;
}
-keepclasseswithmembers class * {
#android.support.annotation.Keep <fields>;
}
-keepclasseswithmembers class * {
#android.support.annotation.Keep <init>(...);
}
# =========================
# ===== LIBGDX CONFIG =====
# =========================
# Don't warn about necessary libs
-dontwarn com.badlogic.gdx.utils.GdxBuild
-dontwarn com.badlogic.gdx.physics.box2d.utils.Box2DBuild
-dontwarn com.badlogic.gdx.jnigen.BuildTarget*
-dontwarn com.badlogic.gdx.jnigen.**
-dontwarn de.matthiasmann.twlthemeeditor.fontgen.**
-dontwarn org.lwjgl.**
-dontwarn org.objectweb.asm.**
-dontwarn org.slf4j.**
-keepnames class com.badlogic.gdx.backends.android.AndroidInput*
-keepclassmembers class com.badlogic.gdx.backends.android.AndroidInput* {<init>(...);}
# LibGDX | Box2D World
#-keepclassmembers class com.badlogic.gdx.physics.box2d.World {
# boolean contactFilter(long, long);
# void beginContact(long);
# void endContact(long);
# void preSolve(long, long);
# void postSolve(long, long);
# boolean reportFixture(long);
# float reportRayFixture(long, float, float, float, float, float);
#}
-verbose
-dontwarn android.support.**
-dontwarn com.badlogic.gdx.backends.android.AndroidFragmentApplication
-dontwarn com.badlogic.gdx.utils.GdxBuild
-dontwarn com.badlogic.gdx.physics.box2d.utils.Box2DBuild
-dontwarn com.badlogic.gdx.jnigen.BuildTarget*
-keepclassmembers class com.badlogic.gdx.backends.android.AndroidInput* {
<init>(com.badlogic.gdx.Application, android.content.Context, java.lang.Object, com.badlogic.gdx.backends.android.AndroidApplicationConfiguration);
}
-keepclassmembers class uk.co.russellwheeler.matcg.android.** {
<init>(...);
}
-keepclassmembers class com.badlogic.gdx.physics.box2d.World {
boolean contactFilter(long, long);
void beginContact(long);
void endContact(long);
void preSolve(long, long);
void postSolve(long, long);
boolean reportFixture(long);
float reportRayFixture(long, float, float, float, float, float);
}
-keep class javax.activation.* { *; }
-dontwarn javax.activation.**
# Crashlytics 2.+
-keep class com.crashlytics.** { *; }
-keep class com.crashlytics.android.**
-keepattributes SourceFile, LineNumberTable, *Annotation*, !LocalVariableTable,!LocalVariableTypeTable
# If you are using custom exceptions, add this line so that custom exception types are skipped during obfuscation:
-keep public class * extends java.lang.Exception
# For Fabric to properly de-obfuscate your crash reports, you need to remove this line from your ProGuard config:
-printmapping mapping.txt
AFAIK, Proguard does not "obfuscate" parameter names in the same way as other names, it just strips them (because unlike field and class names, parameter names are stored in optional debugging symbols). "Parameter names", that you see in decompiler (paramInt, arg0 etc.), are just made up names, autogenerated by decompiler itself. There is no support for applying obfuscation dictionary to parameter names, — you can either strip them completely or keep them (provided that your binaries had them in the first place).
You can try to preserve original parameter names via -keepattribute LocalVariableTable, but that might not work unless you -keep entire class, — Proguard's handling of local variables in modern classfiles is kinda buggy. If you don't do anything, Proguard will default to removing them.
As the other answer already correctly said, ProGuard will not use the obfuscation dictionary for method parameters. Either they are removed or kept with their original names.
In order to keep them, you have to add the following:
-keepparameternames

calling a class constructor present in a dll managed C++

I've a class created in a DLL (which uses /clr runtime, ManagedC++) and a constructor defined in that class. Code as follows:
//Following is defined in something.h//
namespace ABC
{
public ref Class XYZ
{
public: int a;
public: XYZ();
};
//In something.cpp, I've the below code to define the constructor of the class created//
#include something.h
namespace ABC
{
XYZ::XYZ()
{
a = 100;
}
}
Above project is built into a DLL
In another project, I try to use the Class XYZ as follows:
#include something.h
using namespace ABC;
//inside main, I've following code
{
ABC::XYZ^ prq = gcnew ABC:XYZ();
prq->a=200;
......
...
}
In this, I get the an error saying -
unresolved token (06000001) ABC.XYZ::.ctor
Could you please help what's the problem here?
The problem is that the linker can't find the definition of the constructor. It is located in another DLL. In a managed project, you solve that by adding a reference to the assembly. Right-click your project, Properties, Common Properties, Framework and References. Click the Add New Reference button. Use the Project tab if the project is located in the same solution. The Browse tab otherwise.
Also note that you now no longer need the .h file anymore. Declarations are imported from the metadata in the assembly.

Visual C++ 2010: ``unresolved token" LNK2020

I have a VC++ 2010 solution containing two projects: ProjectX and ProjectXTests. In the current configuration, ProjectX builds as a static library and ProjectXTests as a DLL intended to test various methods in ProjectX. Now, in ProjectX I have a class User with a method getUserName(), as follows:
// User.h
public ref class User
{
public:
User(String^ userName);
String^ getUserName();
private:
String^ userName;
};
The constructor and method are implemented in User.cpp. In ProjectXTests, I have a class UserTests, which tests, among other things, the getUserName() method, in a, say, getUserNameTest() method. It is declared in UserTests.h and implemented as follows in UserTests.cpp:
// UserTests.cpp
#include "UserTests.h"
#include "User.h"
void UserTests::getUserNameTest()
{
User^ testUser = gcnew User("name");
Assert::AreEqual("name", testUser->getUserName());
}
In the project properties (Common Properties -> Framework and References) of ProjectXTests, I have added a reference to ProjectX. In VC++ Directories, I have added the appropriate directories for header files and library files. When building the solution, the header file "User.h" is found. However, I get a link error
error LNK2020: unresolved token (06000005) User::getUserName
The same thing happens for all other methods being tested. I just can't figure out why this happens. So far, the only thing I've found to work, is to include the file "User.cpp" instead of "User.h" in "UserTests.cpp", but this seems like cheating. Does anybody know what I might be missing?
Somehow you have to include the code from ProjectX in ProjectXTests. This is not done by literally using the #include directive, instead the simplest is to add the source files from ProjectX to the ProjectXTests project workspace. If ProjectX is made as a static of dynamic library, then link with that instead.