I have an app named MyApp which is linked to a static library MyLibrary
I've added the MyLibrary project to Xcode and added the MyLibrary target to MyApp's target dependencies.
All this works fine, I can set breakpoints, and I'm pretty happy.
The thing is that I want a conditional log in the library :
#ifdef DEBUG
# define MYDebug(msg, ...) NSLog(#"\nDEBUG -> %# \n(%s:%d)",[NSString stringWithFormat:msg, ## __VA_ARGS__], __PRETTY_FUNCTION__,__LINE__);
#else
# define MYDebug(msg, ...)
#endif
So I have two build configuration for my library :
- Debug has "DEBUG=1" in the target's build settings in "preprocessor macros"
- Prod has nothing
And the MyLibrary target is set to build with the Debug build configuration.
This works fine if I build the static library (.a), and include it in a project.
But if it is built by target dependency, it seems that DEBUG is not defined (MYDebug doesn't log anything).
I've also tried to set DEBUG=1 in MyApp's build settings, but it doesn't work.
Is there something I missed, or another way to do it ?
It should just be "DEBUG" instead of "DEBUG=1". Also, to use a macro that needs an Object assignment (NSString, etc) you need to escape most of the characters like # and " etc..
Here is a screenshot of a working project of mine from xCode 4.1:
Related
I create usual hello-world Qt executable via cmake+msvc.
But I cant launch or debug it - the launсh fails by the reason of the absence needed Qt dll.
I found that if I add the
D:\libs\Qt\Qt5.14.2\5.14.2\msvc2017_64\bin;
D:\libs\Qt\Qt5.14.2\5.14.2\msvc2017_64\plugins\platforms;
to the PATH environment variable - the issue gone.
But I dont want that paths in the global environment variables (I plan to have few different versions of the Qt libraries, so all time switching global environment variables will be unusable).
How I could pass the paths to Qt librariles to the cmake for debug/launch executable without modifying the global environment variables?
here is my solution.
open Tools > Options > Debugging > Symbols > add new location.
the location is your qt MSVC bin floder, in my case is "D:\Qt\6.2.2\msvc2019_64\bin".
don't forget select new location, now you can use vs debug qt exe.
You can add the path to your local debugging environment to your CMake generated Visual Studio Solution, either by adding it in the GUI under Configuration Properties -> Debugging -> Environment
or (since CMake 3.13.0) in your CMakeLists.txt by setting the appropriate property on the target.
set_target_properties(exe_target PROPERTIES VS_DEBUGGER_ENVIRONMENT "PATH=D:\libs\Qt\Qt5.14.2\5.14.2\msvc2017_64\bin;D:\libs\Qt\Qt5.14.2\5.14.2\msvc2017_64\plugins\platforms")
Although these properties are prefixed with VS_DEBUGGER_ they apply to both the Debug and Release versions.
Other VS_DEBUGGER_ properties might be of interest too.
See here for documentation.
Is there another a way to link only the release lib of a target when including the target with target_link_libraries for both release and debug configs.
I know target_link_libraries has the options optimize and debug and that it can be done like this
target_link_libraries(current_target
optimized $<TARGET_PROPERTY:lib_target,IMPORTED_IMPLIB_RELEASE>
debug $<TARGET_PROPERTY:lib_target,IMPORTED_IMPLIB_RELEASE>
)
However I generally keep the targets in a list
set(target_list
lib_target1
lib_target2
...
)
and I perform other things on the same list, like getting the binary directory of the target to include in the search path for debugging. Using the optimized and debug options also do not allow the lib_target... properties to be passed along through the current_target. I can work around it just curious if there is another way?
If you link with IMPORTED target, then its configuration-dependent properties refer to "imported configuration". You may always adjust mapping between configurations of your project and imported ones:
Global configuration mapping is adjusted by CMAKE_MAP_IMPORTED_CONFIG_<CONFIG> variables.
The setting below will use Release configuration of every IMPORTED target for any of Release, Debug or RelWithDebugInfo configurations of your project:
set(CMAKE_MAP_IMPORTED_CONFIG_RELEASE Release)
set(CMAKE_MAP_IMPORTED_CONFIG_DEBUG Release)
set(CMAKE_MAP_IMPORTED_CONFIG_RELWITHDEBUGINFO Release)
Note, that these settings should be issued before creating of IMPORTED targets. That is, if such targets are created with find_package() calls, the settings should precede these calls.
Per-target configuration mapping is adjusted by MAP_IMPORTED_CONFIG_<CONFIG> properties.
Settings below do the same as global settings above but only for lib_target1 IMPORTED target:
set_target_properties(lib_target1 PROPERTIES
MAP_IMPORTED_CONFIG_RELEASE Release
MAP_IMPORTED_CONFIG_DEBUG Release
MAP_IMPORTED_CONFIG_RELWITHDEBUGINFO Release)
These settings can be applied only after given IMPORTED target is created, e.g. after find_package() call.
It is worth to mention, that you may also specify fallback imported configurations:
set(CMAKE_MAP_IMPORTED_CONFIG_DEBUG Release Debug)
With such setting, if your project is built in Debug configuration, and some IMPORTED target doesn't have Release configuration, then its Debug configuration will be used. (But if that target has neither Release nor Debug configuration, CMake will emit an error).
I am using CMake to cross compile a C project for an embedded (heterogeneous) multi-core system. The compiler takes an mandatory argument (-t<type>, the target type). This flag has to be set to pass CMake's compiler test. I am adding this flag in a toolchain file as follows:
add_compile_options(-tMYPLATFORMTYPE)
The problem with this approach is, all project files will be compiled with this flag. Is there a way to configure compile flags for the test compilation only, without affecting the main project configuration? (Note: Within the project different files shall have different values for this flag.)
What I am looking for is something like:
set(CMAKE_TRY_COMPILE_COMPILE_OPTIONS "-tMYPLATFORMTYPE")
I could disabled the compile test, but I would prefer to keep it.
You can check the IN_TRY_COMPILE property and set the flag for try-compile configurations only:
get_property(IS_IN_TRY_COMPILE GLOBAL PROPERTY IN_TRY_COMPILE)
if(IS_IN_TRY_COMPILE)
add_compile_options(-tMYPLATFORMTYPE)
endif()
I am trying to build an OS X library using CMake. This libary also includes some amount of resource files (.pdfs used as icon images). In my initial attempts, I have been building the library and the resource files separately as libGeneric.a and generic-Resources.bundle - with, the bundle hosting all the relevant images that libGeneric.a uses.
set (SRC srcfile1.m srcfile2.m)
set (HEADERS srcfile1.h srcfile2.h)
set (ICONS icon1.pdf icon2.pdf)
set (SOURCE_FILE_PROPERTIES ${ICONS} PROPERTIES MACOSX_PACKAGE_LOCATION "Resources")
add_library(generic ${SRC} ${HEADERS})
add_library(generic-Resources MODULE ${ICONS})
set_target_properties(generic-Resources PROPERTIES LINKER_LANGUAGE C) # to suppress CMake error of not able to determine linker language for libary
set_target_properties(generic-Resources PROPERTIES BUNDLE TRUE)
This worked fine, except, I was not able to figure out how to directly include the .bundle in the build process of applications that was using libGeneric.a. The only way I could get CMake to load the bundle was to add it as a source file in the target application. But, since, the bundle had not yet been compiled while running CMake, it would complain that the source file did not exist. As a workaround, I resorted to manually adding the .bundle into xcode after CMake generated the App.xcodeproj file (and I actually compiled the bundle). As this was getting to be cumbersome, I figured I'd try to build a Mac OS X framework instead (to house both the library and the code)
set (SRC srcfile1.m srcfile2.m)
set (HEADERS srcfile1.h srcfile2.h)
set (ICONS icon1.pdf icon2.pdf)
set (SOURCE_FILE_PROPERTIES ${ICONS} PROPERTIES MACOSX_PACKAGE_LOCATION "Resources")
add_library(generic SHARED ${SRC} ${HEADERS} ${ICONS})
set_target_properties(generic PROPERTIES FRAMEWORK TRUE)
set_target_properties(generic PROPERTIES MACOSX_RPATH TRUE) #to suppress cmake warnings on rpath
However, this is creating a framework with just the Icons inside a Resources directory. The code library is missing. I would appreciate some assistance in getting this framework to build correctly. How, do I
get CMake to actually build a library with the indicated source file
and place it inside the framework
get CMake to copy the headers appropriately in the framework.
I am just setting rpath to true now, as I haven't really figured out what to actually do with it. What do I set this to? The objective is to build a private framework, that I would then bundle automatically with my application.
Alternatively, is there an easy way to get CMake to build the bundle file created in my earlier process, and then load that built file into my applications build process.
In a Objective-C project I am using a static library, compilation of this static library depends on some preprocessor macros to be set.
When I set these macros in the project depending on the library the library does not see them. But when I set them in the library project it does work.
Since I want to reuse this library for other projects, I require to set the preprocessor macros for each project depending on the library separately. Is there a solution for this?
Preprocessor maros only have any meaning at compile-time, so any library you build will be specific to the values of these preprocessor macros at the time you built the library. You will either need lots of different versions of your library, built with the different possible values of your preprocessor macros, or you could switch to using a different method to control the behaviour of your library code which will work at run-time, e.g. setting some appropriate parameters through the library API.
This is not an answer per se, but something interesting I discovered while struggling with this same issue.
I have a static library (MyLib) that contains a header for logging (Log.h). I have an application project (MyApp) that uses MyLib. Log.h has some resemblance of this:
#ifdef LOG_LEVEL_DEBUG
# define LogDebug(...) NSLog(__VA_ARGS__)
#else
# define LogDebug(...)
#endif
In MyApp build settings, I can use the preprocessor macro LOG_LEVEL_DEBUG to successfully turn off and on logging. This works when I use LogDebug() in source files found in MyApp. However, the MyLib source files that use LogDebug() are not affected by the MyApp build settings. I have to use the MyLib build settings to affect LogDebug() within the MyLib source files.
I am pretty sure I know what is happening but I'd be open to correction. Below is the scenario where MyApp defines LOG_LEVEL_DEBUG in build settings (enabling debugging) and MyLib does not define it (disabling it).
When MyApp builds, it first compiles MyLib where all of the LogDebug() are replaced within the MyLib source files as no-op (since LOG_LEVEL_DEBUG was not defined). After MyLib is compiled, MyApp is compiled and all of the LogDebug() methods within MyApp source are replaced with NSLog() statements because LOG_LEVEL_DEBUG was defined in the build settings.