Maximum limit on number of Interface libraries in cmake - cmake

does anyone know is there any maximum limit on the number of interface libraries
we can link to a executable target in cmake

Related

Why I am getting BOOST_PARAMETER_MAX_ARITY redefined warning while compiling?

When I am trying to compile my cgal program I get warning include/CGAL/config.h:119: warning: "BOOST_PARAMETER_MAX_ARITY" redefined
#define BOOST_PARAMETER_MAX_ARITY 12
Is is because how I include the cgal header before boost?
What I have seen so far is,
I can see include/CGAL/config.h file defines BOOST_PARAMETER_MAX_ARITY
as #define BOOST_PARAMETER_MAX_ARITY 12 boost also has its own config.h which also defines BOOST_PARAMETER_MAX_ARITY as 8.
I am using CGAL-4.13 and boost-1.68.0
CGAL 3D mesher is using boost parameters and this library requires the definition of a macro for the maximum number of arguments. In CGAL, we need at least 12 as you saw. If you have this error message, it means that boost parameters have been included before including the CGAL header config.h. One solution is to either define yourself the macro to 12 in you compilation unit before including boost (or the other header including it) or to include the CGAL config file first.

"Rosetta" for switching to native CMake CUDA support

I want to switch a CMake-based project of mine to using CMake 3.8 and up's native support for CUDA. I know that, basically, I enable_language(CUDA), then use the regular add_target and add_library instead of the cuda_xxx variants of the same.
However, I'm not sure how to rewrite my code exactly. How do I...:
Set of global CUDA-related CMake variables , e.g. separable compilation, propagation of host flags?
Invoke the CUDA equivalent of CMAKE_CXX_STANDARDand friends?
Add dependencies on CUDA libraries which are not required by default (e.g. NVTX)
... and everything else?
Is there some uniform method to all this, or do I just have to memorize a bunch of new commands?
CMake's native CUDA support works very much in the same way as it does for C and C++ projects. Using CUDA instead of C++ is a similar process to using C instead of C++.
First of all, you should enable CUDA support in your project by adding:
project(myproject LANGUAGES CUDA)
This way, you shouldn't need to run enable_language, and your CMake cache will not be cluttered with the C and C++ compiler configuration generated by the default implied project(myproject LANGUAGES C CXX) you get when you write just project(myproject).
The equivalent of CMAKE_CXX_STANDARD for CUDA is CMAKE_CUDA_STANDARD, much like how there is also CMAKE_C_STANDARD. Additionally, there is CMAKE_CUDA_EXTENSIONS which can be configured to enable / disable compiler specific extensions (i.e. whether to choose -std=c++14 or -std=gnu++14). It's generally the case that if you see CMake variables of the form CMAKE_CXX_..... or CMAKE_C_....., there is an equivalent CMAKE_CUDA_...... And in general, where you see CXX or C in variables and properties, there may be a CUDA equivalent.
set(CMAKE_CUDA_STANDARD 11)
set(CMAKE_CUDA_STANDARD_REQUIRED ON)
set(CMAKE_CUDA_EXTENSIONS OFF)
One thing to note however, is that these particular variables have target-specific equivalents in the form of target properties (both for C++ and CUDA):
set_target_properties(
myprojectlibrary PROPERTIES
CUDA_STANDARD 11
CUDA_STANDARD_REQUIRED ON
CUDA_EXTENSIONS OFF)
As for CUDA-specific features like in the old FindCUDA, you should find these as more target properties just like those in the previous example:
set_target_properties(
myprojectlibrary PROPERTIES
CUDA_SEPARABLE_COMPILATION ON
CUDA_RESOLVE_DEVICE_SYMBOLS ON)
Information about these target properties can be found here, searching on the page for "CUDA".
As for linking to third-party libraries, this can be done the same way as it is done for regular C++ projects:
target_link_libraries(myprojectlib nvtx)
Or if your library isn't defined as a first-class CMake target:
target_link_libraries(myprojectlib ${NVTX_LIBRARY})
target_include_directories(myprojectlib PRIVATE ${NVTX_INCLUDE_DIR})
target_compile_definitions(myprojectlib PRIVATE ${NVTX_DEFINES})
Lastly, if there are any specific nvcc flags required to build your project, these can be set as follows:
target_compile_options(myprojectlib PRIVATE --default-stream=per-thread)
Note that the global user-configurable nvcc flags are also available as the variable CMAKE_CUDA_FLAGS.
Also note that you may have to change PRIVATE to PUBLIC in places where you want particular flags / include directories / compile definitions to also be propagated to targets linking to your library, in the case that myprojectlib is a library and not an executable, which may or may not be desired depending on how your project is structured.

CMake: Is it possible to build an executable from only static libraries and no source?

I would like to build an executable from static libraries (i. e. .a-files) only. This is possible, because the main() function is contained in one of these libraries.
The add_executable() function requires me to provide at least one source file. But this is not what I want to do.
There is no way to do it without a hack. You need at least one *.c or *.cpp file.
What I do is make a dummy null.cpp file (zero bytes) and use that. You can also use /dev/null but that only works on Linux.
file(WRITE null.cpp "")
add_executable(tester
null.cpp
)
target_link_libraries(tester
-Wl,--whole-archive
libtest1
libtest2
libtest3
libtest4
-Wl,--no-whole-archive
gtest_main
)
There are mainly two reasons why a source file is enforced by CMake:
To determine the LINKER_LANGUAGE from the file ending(s)
Not all compilers do support an object/library only link step (for details see below)
And if you move the main() function to library please keep the following in mind: Why does the order in which libraries are linked sometimes cause errors in GCC?
So if you build the libraries with CMake in the same project, I would recommend to change your libraries (at least the one containing your main() function) to an object library:
cmake_minimum_required(VERSION 2.8.8)
project(NoSourceForExe)
file(WRITE main.cc "int main() { return 0; }")
add_library(MyLibrary OBJECT main.cc)
add_executable(MyExecutable $<TARGET_OBJECTS:MyLibrary>)
The add_library() documentation lists a warning here:
Some native build systems may not like targets that have only object files, so consider adding at least one real source file to any target that references $<TARGET_OBJECTS:objlib>.
But those are rare and listed in Tests/ObjectLibrary/CMakeLists.txt:
# VS 6 and 7 generators do not add objects as sources so we need a
# dummy object to convince the IDE to build the targets below.
...
# Xcode does not seem to support targets without sources.
Not knowing which host OS(s) you are targeting, you may just give it a try.
References
CMake Object Lib containing main
CMake/Tutorials/Object Library

static library has big size

I built universal static library with help of this template
The problem that is my library libWrapper.a has size 1.3 mb??? :0
while my source code has 130 kb.
How I can reduce the size of my static lib?
Other strange thing -
Each lib has the same size - 1.3 mb. I supposed that universal (fat) libs should have bigger size.
Also make sure that you set Generate Debug Symbols to NO in your build settings. This can reduce the size of your static library by about 30%.
in terminal run
strip -x [youStaticlib.a]
Description
For dynamic shared libraries, the maximum level of stripping is usually
-x (to remove all non-global symbols).
if you want to know strip other parameter, in terminal run
man strip
You cant. Static libraries include all the code that they reference in the form of frameworks inside their executable.

Why would the size of the final binary be so much smaller than the size of the static library?

This is an iOS question.
I build a static library (a framework in iOS) which is then included in an app. The size of the result binary (500kb) is smaller than the size of the static library (6mb). How does this work? My understanding of static library is that the static library is included in the final binary
Because you are not using all the functions of your library. A static library of archive type .a is a collection of .o object files and only the object files needed in your program are included at link time.
Whenever you statically link an executable, the linker can go ahead and resolve all symbol names (i.e. map them to an address) since all the symbols it will know about you have provided to the linker now (in the form of .o files and .a libraries which are really just a collection of .o files). If there are names that aren't there, you'll get a link error (this is different than dynamic linking where you may be able to load another library at runtime). In your case, you have extra symbols that are unreferenced by the executable. Since these symbols are known to the linker as being unused they are simply removed from the executable output. So your executable will be smaller than the input libraries in this case.