CMake set Visual Studio Linker ->Command Line-> Additional Options [duplicate] - visual-studio

When linking a binary I can use CMAKE_EXE_LINKER_FLAGS to add a flag (let's say -Wl,-as-needed). However, if I link a library this extra flag will not be taken into account. I would need something like CMAKE_LIB_LINKER_FLAGS but I can't find it.
How should I do this?

Note: modern CMake has a better solution than mentioned below (see updates for details).
You can use CMAKE_SHARED_LINKER_FLAGS like:
set (CMAKE_SHARED_LINKER_FLAGS "-Wl,--as-needed")
This question looks like related.
UPD
Thanks to #Bruce Adams who points out that since v3.13 CMake has special command for such purpose: add_link_options.
UPD 2
Thanks to #Alex Reinking who points out that modern CMake doesn't recommend using global settings. It is suggested to give the preference to the property settings before the global ones, so instead of add_link_options that has a global scope, the target_link_options should be used. See Alex's answer for details.

This is how you add linker flags to a target in modern CMake (3.13+):
# my_tgt can be an executable, library, or module.
target_link_options(my_tgt PRIVATE "LINKER:-as-needed")
Note that CMake always passes flags to the configured compiler. Thus, to forward your intended link flags to the linker, you must use the LINKER: prefix. CMake will take care of expanding it to -Wl,-as-needed on GCC, and to -Xlinker -as-needed on Clang.
See the documentation here: https://cmake.org/cmake/help/latest/command/target_link_options.html

It looks like this problem is related to the one I had in CLION. I solved it by adding
{set(CMAKE_CXX_STANDARD_LIBRARIES -ljpeg)}
to CMakeLists.txt.

In CMake 3.10.2, the suggested answer of
set (CMAKE_SHARED_LINKER_FLAGS "-Wl,--as-needed")
did not work for me. The workaround I employed was to use set_target_properties instead.
My CMakeLists.txt file had a line of this sort:
add_library(libraryname MODULE a.cc b.cc c.cc)
After that line, I added this:
set_target_properties(libraryname PROPERTIES LINK_FLAGS "-Wl,-znodelete")

Check out the ucm_add_linker_flags macro of ucm - it deals with appending linker flags to the appropriate CMake variables.

Note that you need to add your linker option without the "-Wl,", namely:
Good:
-DCMAKE_SHARED_LINKER_FLAGS="-fstack-protector"
Wrong:
-DCMAKE_SHARED_LINKER_FLAGS="-Wl,-fstack-protector"

target_link_libraries(target-name PRIVATE -lexpat)
i used this for linking the XML dependencies in my project. replace -lexpat with -l(library name)

Related

How do I tell CMake to output the package search paths?

I'm compiling libdwarf on Windows. In its root CMakeLists.txt, it attempts to find LibElf via:
find_package(LibElf REQUIRED)
LibElf doesn't use CMAKE and I haven't configured it to register itself in any way, so of course the find_package fails. I'd like CMake to print out all the paths under which it is searching for LibElf at runtime. How do I tell CMake to output this? I've tried --trace but that just show me the execution flow through my CMakeLists.txt files--not the locations where CMake itself is presently looking for packages.
I know the documentation for find_package describes where CMake searches, but I can modify that behavior with all sorts of variables, environment variables, and registry settings. I'd like to see where exactly CMake is looking given all my modifications to those items I just mentioned.
I should note that libdwarf includes a cmake/FindLibElf.cmake module. Perhaps what I'm asking for isn't possible if FindLibElf.cmake is free to do whatever it pleases?
Since version 3.17 CMake provides the option --debug-find, which results in output of a ton of debug information about search process of find_package and other find_* commands:
cmake --debug-find <...>
The similar effect could be achieved by setting the variable CMAKE_FIND_DEBUG_MODE.
One may set the variable either in the command line:
cmake -DCMAKE_FIND_DEBUG_MODE=1 <...>
or in the CMakeLists.txt:
set(CMAKE_FIND_DEBUG_MODE 1)

How to build a C++ make project using specific LDFLAGS (Mac OSX)

I have a project that needs to be built using cmake and make. However, I want the project to use libc++ (since its written in C++11) so I need to set the right linker flags. Is there a way I can pass the following flags via command line?
LDFLAGS="-L/usr/local/opt/llvm/lib -Wl,-rpath,/usr/local/opt/llvm/lib"
Or do I need to edit my CMakeLists.txt file? If so how can I add this to the file?
For the more complex linker flags use
set (CMAKE_SHARED_LINKER_FLAGS -Wl,-rpath,/usr/local/opt/llvm/lib)
To add a library search directory (-L) simply add
link_directories(/usr/local/opt/llvm/lib)
See also this and that answer

GCC/G++ : Enable -std=c++11 from environment variable

I have some OpenCV/C++ application which compiles with a CMake definitions file, in which I did not find a way to pass flags to the compiler.
I know that there are the flags C_INCLUDE_PATH CPLUS_INCLUDE_PATH, and all the rest of their friends...
But, is there an environment variable for definition of any other flags, in which I'd be able to define -std=c++11 ?
If you're using CMake, equally easy and nicer solution will be to pass
-DCMAKE_CXX_STANDARD=11 -DCMAKE_CXX_STANDARD_REQUIRED=ON
to CMake.
The easiest but certainly not nicest solution if you want to force it by hand would be:
add_compile_options(-std=c++11)
However CMake should be able to pick the necessary standard for you. Have a look to this answer:
How to detect c++11 support of a compiler with cmake

Purpose of __USE_XOPEN2K8 and how to set it?

I'm trying to compile the gtk stack (the last gtk2 version, 2.24), and I am getting a bunch of errors that seem related. Namely, the __locale_t can't be found from string.h and time.h, and LC_ALL_MASK can't be found either (should be in locale.h).
I found that all of these problems are related to __USE_XOPEN2K8 not being #defined. What is __USE_XOPEN2K8 for, and how can I set it propertly?
For example, do I have to pass a flag to ./configure for glib, gtk, ... or do I have to change something already while building gcc or glibc̲? I'd rather not just sprinkle #define __USE_XOPEN2K8 in to my sources without knowing what it does. Note I'm using gcc-4.6.3 and glibc-2.16.0 which are installed in a nonstandard prefix, as I'm trying to get the gtk libraries to work on an older CentOS (5.8) that only includes older versions.
Also note the missing __locale_t is mentioned in several places, e.g. this bugreport. I could just add #include <xlocale.h> in some files, but it seems the proper solution would be to get __USE_XOPEN2K8 to be set.
Edit: I've found this thread describing the problem. Apparently, headers of the host system get "fixincluded" into the headers of the new compiler. The linked post suggests to edit features.h. Does anyone know if I have to recompile gcc / glibc afterwards (and how to get it to pick up the new features.h, rather than overwriting it)?
When __USE_GNU is defined, __USE_XOPEN2K8 is always defined as well, unless you
are explicitly defining or undefining these macros, which you must not do.
Use _GNU_SOURCE, _XOPEN_SOURCE {500,600,700,...} etc. macros before including
the first header instead. This is the recommended way to select the GNU feature set in glibc headers, together with defining it on the command line (-D_GNU_SOURCE).
Alternatively, you can try specifying GNU extension usage to gcc through the -std command line switch (gnu89, gnu99, and so forth).
On CentOS7 with gcc 4.6 we had to use -D_XOPEN_SOURCE=700 -D__USE_XOPEN2K8
The glibc __USE_* macros are internal macros used to implement feature selection. The supported way to set them is to define feature test macros such as -D_GNU_SOURCE:
Feature Test Macros
These macros are needed because glibc supports many standards and GNU extensions, and these features are in conflict with each other, mostly due to the lack of namespaces in C. For example, C and POSIX allow you to define a global variable called secure_getenv (because the identifier is not reserved or otherwise used by those standards), but such a program will not work if you compile with _GNUS_SOURCE and include <stdlib.h> because glibc provides a function called secure_getenv.
<xlocale.h> is an internal glibc header (a comment within the header file says so) and will no longer be available in glibc 2.26.
As I know when we use the complier, it's behavior depends on some ENV macros, which saved in feature.h. So you can configure your complier by modifyinfg it.
Fisrt,you need use g++ -E youfile > log, to see which feature.h file your complier use, and then use g++ -E -dM /path/to/feature.h>log, to find the __USE_XOPEN2K8, if you can't find it. Add #define __USE_XOPEN2K8 1 at the end of the file.You know may be you have do some configure wrong when you install you complier.

How to set the LDFLAGS in CMakeLists.txt?

I set the CFLAGS in CMake by CMAKE_C_FLAGS.
Is something like this to set LDFLAGS?
It depends a bit on what you want:
A) If you want to specify which libraries to link to, you can use find_library to find libs and then use link_directories and target_link_libraries to.
Of course, it is often worth the effort to write a good find_package script, which nicely adds "imported" libraries with add_library( YourLib IMPORTED ) with correct locations, and platform/build specific pre- and suffixes. You can then simply refer to 'YourLib' and use target_link_libraries.
B) If you wish to specify particular linker-flags, e.g. '-mthreads' or '-Wl,--export-all-symbols' with MinGW-GCC, you can use CMAKE_EXE_LINKER_FLAGS. There are also two similar but undocumented flags for modules, shared or static libraries:
CMAKE_MODULE_LINKER_FLAGS
CMAKE_SHARED_LINKER_FLAGS
CMAKE_STATIC_LINKER_FLAGS
Look at:
CMAKE_EXE_LINKER_FLAGS
CMAKE_MODULE_LINKER_FLAGS
CMAKE_SHARED_LINKER_FLAGS
CMAKE_STATIC_LINKER_FLAGS
If you want to add a flag to every link, e.g. -fsanitize=address then I would not recommend using CMAKE_*_LINKER_FLAGS. Even with them all set it still doesn't use the flag when linking a framework on OSX, and maybe in other situations. Instead use link_libraries():
add_compile_options("-fsanitize=address")
link_libraries("-fsanitize=address")
This works for everything.
You can specify linker flags in target_link_libraries.
For linking against libraries see Andre's answer.
For linker flags - the following 4 CMake variables:
CMAKE_EXE_LINKER_FLAGS
CMAKE_MODULE_LINKER_FLAGS
CMAKE_SHARED_LINKER_FLAGS
CMAKE_STATIC_LINKER_FLAGS
can be easily manipulated for different configs (debug, release...) with the ucm_add_linker_flags macro of ucm

Resources