I would like to compile the cmake file from Manyears 1.1.2 sources, but I got the errors as below:
WARNING : manyears GUI will not be compiled because Qt4 not found
-- Buiding ManyEarsLib Library...
CMake Error at dsplib/CMakeLists.txt:75 (set_target_properties):
set_target_properties called with incorrect number of arguments.
-- Buiding RTAudio Library...
CMake Error at example/CMakeLists.txt:22 (set_target_properties):
set_target_properties called with illegal arguments, maybe missing a
PROPERTIES specifier?
And the original program has been written as below:
target_link_libraries(ManyEarsLib )
set_target_properties(ManyEarsLib PROPERTIES LINK_FLAGS ${MANYEARS_LINK_FLAGS} OUTPUT_NAME man-years)
add_executable(manyears_console manyears_console.c)
set_target_properties(manyears_console PROPERTIES LINK_FLAGS ${MANYEARS_LINK_FLAGS})
target_link_libraries(manyears_console ManyEarsLib -lm)
Could somebody tell me what is the problem and how to risolve it?
Thanks a lot.
Lun
Command set_target_properties may only set single-value properties.
But you attempt to set property LINK_FLAGS, which is generally multi-value (a list), but in your case it is simply empty. That is why first invocation detects incorrect number of arguments (it should be even), and the second invocation detects insufficient number of arguments (is should be 4 at least).
For set multi-value properties or for clear them use command set_property:
# Multi-value (or empty) property
set_property(TARGET ManyEarsLib PROPERTY LINK_FLAGS ${MANYEARS_LINK_FLAGS})
# Single-value property
set_target_properties(ManyEarsLib PROPERTIES OUTPUT_NAME man-years)
# Multi-value (or empty) property again
set_property(TARGET manyears_console PROPERTY LINK_FLAGS ${MANYEARS_LINK_FLAGS})
or even
# Multi-value (or empty) property for several targets
set_property(TARGET ManyEarsLib manyears_console PROPERTY LINK_FLAGS ${MANYEARS_LINK_FLAGS})
# Single-value property for single target
set_target_properties(ManyEarsLib PROPERTIES OUTPUT_NAME man-years)
Related
In the following CMake code snippet, I am confused by the if elseif check. My understanding is that BL will always be "Ei", so there is no need to check other values. Are there any scenarios where BL could be overwritten by something else? I am new to CMake so need some help here.
set(BL "Ei" CACHE STRING "library")
set_property(CACHE BL PROPERTY STRINGS "Ei;AT;Op")
message(STATUS "The backend of choice:" ${BL})
if(BL STREQUAL "Ei")
...
elseif(BL STREQUAL "AT")
...
elseif(BL STREQUAL "Op")
...
else()
message(FATAL_ERROR "Unrecognized option:" ${BL})
endif()
The code set(BL "Ei" CACHE STRING "library") defines a CMake cache variable. However, without a FORCE option in the set statement, that means that it will not be overwritten if the variable was previously defined in the cache.
One way for a user to set a different value for BL would be on the cmake command line. For example: cmake ../sourcedir -DBL:STRING=AT
By entering the variable in the cache as type STRING (as opposed to type INTERNAL) that also makes the variable available to be configured in cmake-gui or in ccmake. (Furthermore, the set_property(... STRINGS ...) directive tells cmake-gui to produce a drop-down list containing Ei, AT, and Op to select from. However, this isn't enforced for setting the variable from the command line, which is why it's still a good idea to have the default case signalling an error.)
See the section "Set Cache Entry" under CMake's documentation for set for more information.
I've been told it's bad practice to do things like seting CFLAGS directly in CMake, and that, instead, I should use the target_compile_definitions() command.
Ok, but - what if I want to use similar/identical definitions for multiple (independent) targets? I don't want to repeat myself over and over again.
I see three possible ways:
The preferred one using target_compile_definitions(... INTERFACE/PUBLIC ...) which would self-propagate the compiler definitions to targets depending on it via target_link_libraries() command.
Using the set_property(TARGET target1 target2 ... APPEND PROPERTY COMPILE_DEFINITIONS ...) to set the same definitions to multiple targets.
You may still use the "old commands" of add_definitions() and remove_definitions() to modify COMPILE_DEFINITIONS directory property (which would pre-set all COMPILE_DEFINITIONS target properties in this directories scope).
References
Is Cmake set variable recursive?
CMake: Is there a difference between set_property(TARGET ...) and set_target_properties?
tl;dr: You can iterate the targets in a loop.
If you have a bunch of targets with some common/similar features, you may want to simply manipulate them all in a loop! Remember - CMake is not like GNU Make, it's a full-fledged scripting language (well, sort of). So you could write:
set(my_targets
foo
bar
baz)
foreach(TARGET ${my_targets})
add_executable(${TARGET} "${TARGET}.cu")
target_compile_options(${TARGET} PRIVATE "--some_option=some_value")
target_link_libraries(${TARGET} PRIVATE some_lib)
# and so on
set_target_properties(
${TARGET}
PROPERTIES
C_STANDARD 99
C_STANDARD_REQUIRED YES
C_EXTENSIONS NO )
endforeach(TARGET)
And you could also initialize an empty list of targets, then add to it here-and-there, and only finally apply your common options and settings to all of them, centrally.
Note: In this example I added PRIVATE compile options, but if you need some of them to propagate to targets using your targets, you can make them PUBLIC).
another neat solution is to define an interface library target (a fake target that does not produce any binaries) with all required properties and compiler definitions, then link the other existing targets against it
example:
add_library(myfakelib INTERFACE)
target_compile_definitions(myfakelib INTERFACE MY_NEEDED_DEFINITION)
add_executable(actualtarget1 main1.cpp)
add_executable(actualtarget2 main2.cpp)
set_property(
TARGET actualtarget1 actualtarget2
APPEND PROPERTY LINK_LIBRARIES myfakelib
)
refs:
https://cmake.org/cmake/help/latest/command/add_library.html#interface-libraries
What is the difference between
COMPILE_FLAGS: Additional flags to use when compiling this target's sources.
and
COMPILE_OPTIONS: List of options to pass to the compiler.
In terms of resulting VS2010 solution these commands produce the same result:
target_compile_options(target PRIVATE "/option=test1")
set_target_properties(target PROPERTIES COMPILE_FLAGS "/option=test1")
set_target_properties(target PROPERTIES COMPILE_OPTIONS "/option=test1")
COMPILE_OPTIONS is a list, but COMPILE_FLAGS is a string.
set_target_properties(target PROPERTIES
COMPILE_OPTIONS "/option=test1;/option2=test2")
set_target_properties(target PROPERTIES
COMPILE_FLAGS "/option=test1 /option2=test2")
You can more-easily append to a list than to a string.
Also, COMPILE_OPTIONS is properly escaped, whereas some characters in COMPILE_FLAGS may need to be escaped manually or cause problems.
Can be used to the same end, but flags are associated with some target enviroment. So you could use different sets of flags for different enviroments.
Here is my simple CMakeLists.txt file:
include_directories (${CMAKE_SOURCE_DIR}/common)
find_package(Threads)
add_library (libusbmuxd SHARED libusbmuxd.c sock_stuff.c ${CMAKE_SOURCE_DIR}/common/utils.c)
find_library (PTHREAD pthread)
target_link_libraries (libusbmuxd ${CMAKE_THREAD_LIBS_INIT})
# 'lib' is a UNIXism, the proper CMake target is usbmuxd
# But we can't use that due to the conflict with the usbmuxd daemon,
# so instead change the library output base name to usbmuxd here
set_target_properties(libusbmuxd PROPERTIES OUTPUT_NAME usbmuxd)
set_target_properties(libusbmuxd PROPERTIES VERSION ${LIBUSBMUXD_VERSION})
set_target_properties(libusbmuxd PROPERTIES SOVERSION ${LIBUSBMUXD_SOVERSION})
install(TARGETS libusbmuxd
ARCHIVE DESTINATION lib${LIB_SUFFIX}
LIBRARY DESTINATION lib${LIB_SUFFIX}
)
install(FILES usbmuxd.h usbmuxd-proto.h DESTINATION include)
This gives me an error:
CMake error at CMakeLists.txt:12 (set_target_properties):
set_target_properties called with incorrect number of arguments
CMake error at CMakeLists.txt:13 (set_target_properties):
set_target_properties called with incorrect number of arguments
Those are the second and third set_target_properties. The first set_target_properties never had that problem?
(If you haven't realized already, I'm trying to build usbmuxd-1.0.4)
The format of SET_TARGET_PROPERTIES is:
SET_TARGET_PROPERTIES(
target1 target2 ... targetM
PROPERTIES
prop1 val1 prop2 val2 ... propN valN
)
The reason for your problem is that your variables LIBUSBMUXD_VERSION and LIBUSBMUXD_SOVERSION are undefined, and so the syntax of your command is:
SET_TARGET_PROPERTIES(target PROPERTIES name)
Instead of:
SET_TARGET_PROPERTIES(target PROPERTIES name value)
To fix this, try quoting the variables; using "${LIBUSBMUXD_SOVERSION}" should ensure that it takes on the value of the empty string even if the variable is undefined, thereby adhering to the syntax.
SET_TARGET_PROPERTIES(
wtdbo
PROPERTIES
VERSION ${VERSION_SERIES}.${VERSION_MAJOR}.${VERSION_MINOR}
SOVERSION ${WTDBO_SOVERSION}
DEBUG_POSTFIX "d"
)
The error is:
CMake Error at src/Wt/Dbo/CMakeLists.txt:18 (SET_TARGET_PROPERTIES):
set_target_properties called with incorrect number of arguments
If I remove it it configures just fine.
Any idea why?
Thanks,
Omer
Remember that this is a macro, so symbols are replaced before being evaluated. This means that symbols that are empty strings will be replaced to nothing before being evaluated. Thus, if WTDBO_SOVERSION is "" then
SET_TARGET_PROPERTIES(wtdbo PROPERTIES SOVERSION ${WTDBO_SOVERSION})
would become
SET_TARGET_PROPERTIES(wtdbo PROPERTIES SOVERSION)
and this would trigger the error. If empty strings are valid for your purpose then surround the symbol in quotes. e.g.
SET_TARGET_PROPERTIES(wtdbo PROPERTIES SOVERSION "${WTDBO_SOVERSION}")
Are you sure you have the variables set correctly? I've checked with this CMakeLists.txt file, and it works correctly:
CMAKE_MINIMUM_REQUIRED(VERSION 2.6)
PROJECT(test CXX)
ADD_LIBRARY(wtdbo SHARED test.cc)
SET(WTDBO_SOVERSION 1)
SET(VERSION_SERIES 1)
SET(VERSION_MAJOR 0)
SET(VERSION_MINOR 0)
SET_TARGET_PROPERTIES(
wtdbo
PROPERTIES
VERSION ${VERSION_SERIES}.${VERSION_MAJOR}.${VERSION_MINOR}
SOVERSION ${WTDBO_SOVERSION}
DEBUG_POSTFIX "d"
)
However, if I comment out the SET(WTDBO_SOVERSION 1) line I get the same error message as you do. The help for set_target_properties is as follows, so you are definitely doing the right thing:
Targets can have properties that
affect how they are built.
set_target_properties(target1 target2 ...
PROPERTIES prop1 value1
prop2 value2 ...)
Set properties on a target. The
syntax for the command is to list all
the files you want to change, and then
provide the values you want to set
next. You can use any prop value pair
you want and extract it later with the
GET_TARGET_PROPERTY command.