I am moving an Android project from ndk to CMake.
In Application.mk we set following flag:
APP_ALLOW_MISSING_DEPS := true
But I couldn't find equivalent cmake flag for this. Can this be set from cmake arguments?
If you need this flag in ndk-build it means your Android.mk is wrong. That flag tells ndk-build to ignore garbage in your build script. It makes unknown dependencies exactly as meaningful as whitespace. The same behavior is achieved by removing the uses of the unknown deps from your Android.mk. ndk-build tells you this in the warning:
Note that old versions of ndk-build silently ignored this error case. If your project worked on those versions, the missing libraries were not needed and you can remove those dependencies from the module to fix your build.
Alternatively, set APP_ALLOW_MISSING_DEPS=true to allow missing dependencies.
Related
Prepare the following (erroneous) CMakeLists.txt file:
cmake_minimum_required(VERSION 3.10)
project(foo)
add_executable(foo foo.cpp)
add_compile_definitions(BAR=123)
add_compile_definitions is new in CMake 3.12, so processing the above file in CMake 3.10 will result in an error.
CMake Error at CMakeLists.txt:4 (add_compile_definitions):
Unknown CMake command "add_compile_definitions".
However, using CMake 3.12 or later, no errors or warnings are output.
Therefore, as long as you are using CMake 3.12 or later, you will not notice the error.
(In this case, we can use add_compile_options instead of add_compile_definitions, but that is not the main issue.)
You may say, "you shouldn't write cmake_minimum_required(VERSION 3.10) because you are not using CMake 3.10, you should write the version you are actually using".
However, there may be cases where modifications are made to an existing code base.
Is there any way to realize that when you do so, you inadvertently write something that is not usable in the specified version?
For example, is there a tool like lint that can check for features that are not available in a given version?
Currently, is the only way to do this is to install the specified version of CMake?
You have to test with the minimum required version. But even if no error occurs, your test might be incomplete, because you only test these parts of the code, that you are actually running. If your setup does not provide an optional dependency or you did not set a flag, the code executed for this dependency or flag will not be tested.
Depending on your setup, it makes sense to have a continuous testing (GitLab, Jenkins, GitHub actions) that runs your CMake code with CMake in the minimum required version. Then you get early warning that someone added code that is above the required CMake version and you should revert it or increase the requirements.
It is really not a satisfying answer and in general not a satisfying situation.
usr1234567 wrote a good answer, but let me add an additional point:
I think you (and many others; you're in good company) are misunderstanding the guarantee made by cmake_minimum_required(VERSION X). Many people believe it means the following:
This project will build with version X.
That is not the case at all. What it actually promises is:
If this project builds with version X, then it will build on versions Y > X.
That is to say, it is a backwards compatibility guarantee, not a forwards compatibility guarantee. You cannot author a project with a newer version of CMake and expect it to work with older versions without testing it.
When specify linkerOpts, we need set absolute path for -L option, but it's easy to break.
In older version, setting linkerOpts in build.gradle could work, but in 1.3.50, it warns that "-linker-option(s)/-linkerOpts/-lopt option is not supported by cinterop. Please add linker options to .def file or binary compilation instead.", and build do fail with "Undefined symbols" error.
What could I do?
This option is going to be deprecated once, so the warning was intentionally added after the 1.3.50 release. The motivation here is that one should prefer to set all linker options, even platform-specific, via .def file.
But, the build should not break apart in this case. Can you add the script contents, to make it clearer - what exactly led to the error?
UPD: After the GH project was shared in the comments I want to add some details here. This problem is described in the documentation here, this part:
Often it's necessary to specify target-specific linker options for a binary which uses a native library. It can be done using the linkerOpts property of the binary.
So, in this particular case, it will be correct to add the option to the binaries section instead of the cinterops. In the end, I made things together with
binaries {
all {
linkerOpts = ['-L'+rootProject.projectDir+'/libs/NativeBase64/iOS/', '-lNativeBase64']
}
}
I have a CMake file that contains a target that depend on a package, namely Java, as well a target that dose not require Java.
I would like to be able to build the not-requiring-java target w/o requiring java.
add_executable(nojava_targ "")
add_executable(java_targ "")
The trouble is once CMake sees the requiring-java-project on a machine w/o Java, CMake errors out, refusing to build the Makefile. This prevents the not-requiring-java target from building even though it doesn't need java.
find_package(JNI COMPONENTS Development)
target_include_directories( java_targ PRIVATE
${JTARG_INCLUDES}
${JNI_INCLUDE_DIRS})
CMake Error: The following variables are used in this project, but they are set to NOTFOUND.
Please set them or make sure they are set and tested correctly in the CMake files:
/mnt/src/prjx/JAVA_INCLUDE_PATH
used as include directory in directory /mnt/src/prjx/
Is there some way to signal to CMake that this package is required, but only by some targets?
find_package will set JNI_FOUND to true if it finds the package, so add any Java-target
commands only if JNI_Found is true. Something like this:
find_package(JNI COMPONENTS Development)
if(JNI_FOUND)
add_executable(java_targ java_targ.cpp)
target_include_directories(java_targ PRIVATE
${JTARG_INCLUDES}
${JNI_INCLUDE_DIRS})
endif()
In the 2.x version of CMake, the cmake option CMAKE_BUILD_TYPE controlled options to be passed to the compiler. For example, if CMAKE_BUILD_TYPE=RelWithDebInfo then the options passed to the compiler was CMAKE_CXX_FLAGS_RELWITHDEBINFO for C++ and CMAKE_C_FLAGS_RELWITHDEBINFO for C (http://binglongx.wordpress.com/tag/cmake_build_type/).
In the new 3.x version of CMake there are commands add_compile_options and target_compiler_options for adding options to the compiler (What is the modern method for setting general compile flags in CMake?).
Questions
How do I define which build type CMake should use? Is it still, for example, cmake -DCMAKE_BUILD_TYPE=Debug?
How do I make use of this build type in my CMakeLists.txt?
Has CMake defined all the build types, or can I define custom, additional, build types?
Has CMake set any default compiler options for each of the build types (for example -g for the Debug build type)?
Please try to stick to a single question per question in the future. You might risk getting closed as too broad otherwise. Also, you are more likely to get good answers for well-defined, precise questions.
How do I define which build type CMake should use? Is it still, for
example, cmake -DCMAKE_BUILD_TYPE=Debug?
Yes, this did not change.
How do I make use of this build type in my CMakeLists.txt?
Use generator expressions. For example:
target_compile_options(my_program PUBLIC $<$<CONFIG:Debug>:-Werror>)
# Warnings are errors for debug build only
Has CMake defined all the build types, or can I define custom,
additional, build types?
You can add your own type if the defaults don't cut it for you. Note though that this can be a bit fiddly, so I wouldn't do it unless you have good reasons. Take a look at CMAKE_CONFIGURATION_TYPES.
Has CMake set any default compiler options for each of the build types
(for example -g for the Debug build type)?
CMake does a pretty good job at choosing the right defaults for the different configurations. In particular, Debug and RelWithDebInfo builds generate symbols correctly (-g on gcc) and Release builds are optimized quite well.
During compilation, cmake shows this kind of message :
"Dependee is newer than depender "
to explain why a file needs to be recompiled.
How can I get rid of this message?
Sorry, the problem is in Buildroot. The root makefile export VERBOSE environment variable (the variable is empty, but Cmake only tests if the variable is defined, not its value).
Actually, you can define CMAKE_NO_VERBOSE environment variable to suppress generating detailed info from cmake. You can also call make with argument CMAKE_NO_VERBOSE=1 which will have the same effect.