How to handle not finding OpenCV in source code - c++

I have built a C++ library that depends on OpenCV. However, sometimes I don't need to use OpenCV, and I compile the code without it.
The idea is, when the OpenCV_Found variable in CMake is true, there would be a pre-processor variable similar to the OpenCV_Found variable, but in the C++ code. In other words, I want to do something like this:
#ifdef OpenCV_Found
#include <opencv2/core/core.hpp>
#endif
My question is:
Does OpenCV provide a similar variable like that? Or do I have to define it manually, and send it to the target compilation flags?

You can use CMake to forward the OpenCV_Found CMake definition to your C++ source code. You can use a generator expression in target_compile_definitions() like this:
add_executable(MyExe ${MY_SOURCES})
target_compile_definitions(MyExe PUBLIC $<$<BOOL:${OpenCV_Found}>:OpenCV_Found>)
This will add OpenCV_Found as a pre-processor definition to the MyExe target when the ${OpenCV_Found} CMake variable evaluates to True. When the CMake variable ${OpenCV_Found} evaluates to False (case-insensitive equal of 0, FALSE, OFF, N, NO, IGNORE, or NOTFOUND), the OpenCV_Found pre-processor definition is omitted.

Related

Is there a cmake compile feature for c++17's charconv?

I have written some code that make use c++17's charconv, that I can compile just fine with g++ 9. Even though I have set the std to c++17 in my CMakeLists.txt, cmake insists on using c++ 7.5, which does not support charconv.
How do I tell cmake that I need a compiler that supports charconv ?
I see no switch in CMAKE_CXX_KNOWN_FEATURES.
Here is my CMakeLists.txt
cmake_minimum_required(VERSION 3.17)
file(GLOB CLIENT_SRC "srcs/*.cpp")
include_directories("includes")
add_executable(client ${CLIENT_SRC})
set_target_properties(client PROPERTIES OUTPUT_NAME "distff-client")
target_compile_features(client PUBLIC cxx_std_17 )
Not a cmake guy... and I don't really understand cmake's approach to compile features here. But in C++ in general, we now use feature-test macros to detect the presence of features. You're looking specifically for __cpp_lib_to_chars.
I think you want to require compilation of this program:
#if __has_include(<version>)
# include <version>
#elif __has_include(<charconv>)
# include <charconv>
#else
# error "neither <version> nor <charconv> available to test"
#endif
#ifndef __cpp_lib_to_chars
# error "tochars not implemented"
#endif
Which can probably be generalized to something you can configure_file() for an arbitrary library feature (just pull out the header name and the macro name, and probably also check for the macro having the minimum required value).
Either way, if you try_compile() the resultant source file, you could probably get the behavior you want?
Not a CMAKE expert, but the easiest would be to set the CXX environment variable. Like so:
export CXX="/usr/bin/x86_64-linux-gnu-g++-9"
see more at How to specify a compiler in CMake?

CMake: Set different name for #cmakedefine variable

I know you can use CMake's configure_file to make CMake variables available to your program. For example, I can use
#define ${CMAKE_BUILD_TYPE}
resulting in
#define Release
However, to keep my code more readible, I would prefer to define
#define BUILD_TYPE_RELEASE
Is there a simple way to achieve this?
Here is a fairly simple way to solve it:
In CMakesLists.txt:
if (NOT CMAKE_BUILD_TYPE)
set (CMAKE_BUILD_TYPE Release)
endif (NOT CMAKE_BUILD_TYPE)
string (TOUPPER ${CMAKE_BUILD_TYPE} BUILD_TYPE_NAME)
configure_file (config.h.in config.h)
And in config.h.in:
#define BUILD_TYPE_${BUILD_TYPE_NAME}
I am, however, still curious if there is a more elegant solution.
This is more a question of your preferred programming style (configuration files vs. compiler definitions).
In your case I would use add_definitions() or directly modify/append COMPILE_DEFINITIONS directory property (using generator expressions also supports multi-configuration environments):
set_property(
DIRECTORY
APPEND
PROPERTY
COMPILE_DEFINITIONS "BUILD_TYPE_$<UPPER_CASE:$<CONFIG>>"
)
Most simplified Debug/Release Check
You can also check what compiler definitions CMake does pre-define. Without having to modify/add something to your CMakeLists.txt files you could simply check for NDEBUG definition (set for Release builds across platforms) in you C/C++ code:
#ifdef NDEBUG
...
#endif
References
CMake: How to pass preprocessor macros
How to check if a CMake build directory build type is Debug or Release?
What predefined macro can be used to detect debug build with clang?

C++ Macro defined from outside .cpp or .hpp

I want to do something like an application that is build in debug or release mode.
Is it possible to define a macro outside the .cpp or .hpp?
I am using CMake. I have seen that add_definitions(...) is doing something like this. Shall I create two executables proj and proj_debug and for debug define a macro with add_definitions(...)? Is this a good approach? If not, how would you suggest me to do?
Use something like this:
target_compile_definitions(myproj PRIVATE $<$<CONFIG:Debug>:MY_DEBUG_MACRO>)
http://www.cmake.org/cmake/help/v3.0/manual/cmake-generator-expressions.7.html
http://www.cmake.org/cmake/help/v3.0/command/target_compile_definitions.html
http://www.cmake.org/cmake/help/v3.0/manual/cmake-buildsystem.7.html
This works with all generators and is the documented, right, supported way of doing it (and implemented by me :) ).
Man g++ http://linux.die.net/man/1/g++
Look for the -D option for defining macros
and you can configure your makefiles to set that option http://www.cmake.org/Wiki/CMake_Useful_Variables
set(CMAKE_CXX_FLAGS "-g -Wall -Dxxxx")
To define Macro in the different file can be done by following ways:
1) You can define Macro in any other .h file.
and include the file in .cpp file.
This can help you to define Macro in different file
To check the Macro for Debug and Release version use _Debug or _Release Macro.
2) Another way to do this is By using the way told by #Soren.
using set(CMAKE_CXX_FLAGS "-g -Wall -Dxxxx")
like this. Shall I create two executables proj and proj_debug and for debug
No need.
With cmake you can change the CMAKE_BUILD_TYPE variable when configuring your project. Then in your CMakeLists.txt you can do something like:
if(NOT CMAKE_BUILD_TYPE STREQUAL "Release")
add_definitions(-DMY_DEBUG_MACRO)
endif()
Then you can easily configure your project twice (in two directories): once with CMAKE_BUILD_TYPE set to Debug and once CMAKE_BUILD_TYPE set to Release.

port a variable form make to Cmake

Our Library uses Cmake while the Overall system uses Make file for build.
I want to port the value of a variable (preprocessor macro) defined in the makefile to Cmakefile and use it as preprocessor marco in source codes of my library.
How to do that?
You can define variable at CMake invocation like so:
cmake -DMY_VAR=ON <path_to_CMakeLists.txt>
Then later in your CMake file:
if (MY_VAR)
add_definitions(-DENABLE_MY_VAR)
endif()
And finally in your code:
#ifdef ENABLE_MY_VAR
// Your code
#endif

Include another CMake Project as Library

I have decided to make a C++-Qt-GUI for a C program (both languages I don’t know), using KDevelop, which in turn uses CMake.
The C source has no header, so I made one, and migrated some structs into it, as well as the declaration of the only function in the C source i need to call.
The problem is that I can’t call it, because either CMake doesn’t find the C file (and hence the definition), or, when I add the C source to my source set in the CMakeLists.txt, it complains that both my main.cpp and the C source file have main functions.
How do I tell CMake that it should only make the function from the C file available which I declared in the header?
here is it:
project(oregengui)
cmake_minimum_required(VERSION 2.6)
find_package(Qt4 REQUIRED)
include_directories(${QT_INCLUDES} ${CMAKE_CURRENT_BINARY_DIR})
set(oregengui_SRCS oregengui.cpp main.cpp qrangeslider/qrangeslider.cpp)
#as soon as i add oregengui/oregengui.c, it won’t work because of the main function
qt4_automoc(${oregengui_SRCS})
add_executable(oregengui ${oregengui_SRCS})
target_link_libraries(oregengui ${QT_QTCORE_LIBRARY} ${QT_QTGUI_LIBRARY})
PS: I don’t want to change the C source too much, since it is a independant project. I guess the developer will accept the introduction of the header, but not much more.
Try compiling C file as library and linking it with executable.
add_library(clib oregengui/oregengui.c)
[...]
add_executable(oregengui ${oregengui_SRCS})
target_link_libraries(oregengui ${QT_QTCORE_LIBRARY} ${QT_QTGUI_LIBRARY} clib)
I'm a bit rusty on this, but could you do something along the lines of:
In oregengui.c
#if !defined MYGUIPROJ
int main() {
...
}
#endif
In your CMakeLists that you want both in:
add_definitions( -DMYGUIPROJ )
The compiler should then ignore your second main function.
Your program cannot contain two main functions at the same time. Just try to rename the main function in the C file you included to your project. This is not a big change to the source, but you will have to do it locally.
if your C program has a main function, then it can be executed independently. So why not use the QProcess::execute() method to invoke the application from qt and get the output?