Can't link MacOS frameworks with CMake - ios

I'm trying to build a subproject with cmake (it's not an xcode project or even an app for iphone, the result is cross-platform console executable, which #includes some inherited from C++ abstract classes, written in objective-c++)
I'm using this guide to link mac os frameworks: http://www.vtk.org/Wiki/CMake:HowToUseExistingOSXFrameworks
and this macro:
macro(ADD_FRAMEWORK fwname appname)
find_library(FRAMEWORK_${fwname}
NAMES ${fwname}
PATHS ${CMAKE_OSX_SYSROOT}/System/Library
PATH_SUFFIXES Frameworks
NO_DEFAULT_PATH)
if( ${FRAMEWORK_${fwname}} STREQUAL FRAMEWORK_${fwname}-NOTFOUND)
MESSAGE(ERROR ": Framework ${fwname} not found")
else()
TARGET_LINK_LIBRARIES(${appname} ${FRAMEWORK_${fwname}})
MESSAGE(STATUS "Framework ${fwname} found at ${FRAMEWORK_${fwname}}")
endif()
endmacro(ADD_FRAMEWORK)
This is the important part in CMakeLists.txt
project(myprojectname)
........
add_executable(mytarget src/mytarget.cpp)
add_framework(CoreMedia mytarget)
add_framework(CoreVideo mytarget)
add_framework(AVFoundation mytarget)
add_framework(Foundation mytarget)
........
And that's what i have when trying to build:
WARNING: Target "mytarget" requests linking to directory "/Applications/Xcode.app/Contents/Developer/Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS6.0.sdk/System/Library/Frameworks/CoreMedia.framework". Targets may link only to libraries. CMake is dropping the item.
WARNING: Target "mytarget" requests linking to directory "/Applications/Xcode.app/Contents/Developer/Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS6.0.sdk/System/Library/Frameworks/CoreVideo.framework". Targets may link only to libraries. CMake is dropping the item.
WARNING: Target "mytarget" requests linking to directory "/Applications/Xcode.app/Contents/Developer/Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS6.0.sdk/System/Library/Frameworks/AVFoundation.framework". Targets may link only to libraries. CMake is dropping the item.
WARNING: Target "mytarget" requests linking to directory "/Applications/Xcode.app/Contents/Developer/Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS6.0.sdk/System/Library/Frameworks/Foundation.framework". Targets may link only to libraries. CMake is dropping the item.
It actually finds all these frameworks, but can't link, which produces a lot of linker errors. I'm pretty sure that that's the reason because i made a testproj using XCode and it has the same errors till i linked all the needed frameworks.
When i just use
FIND_LIBRARY(COREMEDIA_LIB CoreMedia)
...
then COREMEDIA_LIB is set to NOTFOUND - what's going on? :/
I googled a lot but nothing :( Feeling pretty much lost there.

Got the thing: you have to link NOT the frameworkname.framework folder in the TARGET_LINK_LIBRARIES, but the fwname.framework/fwname file! Now it works that way.
The changed macro is this:
macro(ADD_FRAMEWORK fwname appname)
find_library(FRAMEWORK_${fwname}
NAMES ${fwname}
PATHS ${CMAKE_OSX_SYSROOT}/System/Library
PATH_SUFFIXES Frameworks
NO_DEFAULT_PATH)
if( ${FRAMEWORK_${fwname}} STREQUAL FRAMEWORK_${fwname}-NOTFOUND)
MESSAGE(ERROR ": Framework ${fwname} not found")
else()
TARGET_LINK_LIBRARIES(${appname} "${FRAMEWORK_${fwname}}/${fwname}")
MESSAGE(STATUS "Framework ${fwname} found at ${FRAMEWORK_${fwname}}")
endif()
endmacro(ADD_FRAMEWORK)
Hope it will be useful for someone...

Related

Error in Cannot specify link libraries for target "Opencvtest" which is not built by this project [duplicate]

I am implementing CMake in my code but I'm getting the error
"Cannot specify link libraries for target "Qt5::Widgets" which is not built by the project".
Below are the contents of the CMakeLists.txt:
#Specify the version being used aswell as the language
cmake_minimum_required(VERSION 2.6)
#Name your project here
project(eCAD)
#Sends the -std=c++11 flag to the gcc compiler
ADD_DEFINITIONS(-std=c++11)
#This tells CMake to main.cpp and name it eCAD
add_executable(eCAD main.cpp)
#include the subdirectory containing our libs
add_subdirectory (gui)
include_directories(gui)
#include Qt directories
find_package(Qt5Widgets)
find_package(Qt5Core)
find_package(Qt5Designer)
SET(QT_USE_QTDESIGNER ON)
#link_libraries
target_link_libraries(Qt5::Widgets Qt5::Core)
In addition to the accepted answer: An important detail is to place target_link_libraries after the add_executable and find_package lines, so all linked components are known.
The first argument of target_link_libraries is the target name:
target_link_libraries(eCAD Qt5::Widgets Qt5::Core)
Also, do not confuse target name with the project name:
a command project specifies a project name, but
a target is the one created with add_executable, add_library or add_custom_target.
The error message is about the target.
Set you_lib_name before setting target_link_libraries
set(you_lib_name libname)
target_link_libraries(you_lib_name Qt5::Widgets Qt5::Core)

Link to fat Static Library inside Swift Package

I’m trying to build a Swift Package that wraps a fat static library written in C: libndi_advanced_ios.a from NewTek's Apple Advanced NDI SDK.
I am having trouble linking the pre-compiled library (only headers files and .a binary package is available) to my Swift Package. I have done a lot of research and tried different solutions, but none of them worked. Here is a quick list:
Cannot bundle in an XCFramework because libndi_advanced_ios.a supports multiple platforms (arm_v7, i386, x86_64, arm64) and xcodebuild -create-xcframework return the error binaries with multiple platforms are not supported (this solution is discussed on Swift Forums too);
Using .linkedLibrary in targets as suggested on SPM Documentation (that is outdated) gives the warning system packages are deprecated; use system library targets instead, and I don’t even remember if it builds successfully;
Playing around with different flags and settings (like linkerSettings) has not been successful. Maybe I just missed the right combination.
I can link dozens of Stackoverflow's questions and other posts that didn’t help, but it will be useless (a, b, c).
At the moment I have this configuration:
With Package.swift that contains the following code:
let package = Package(
name: "swift-ndi",
platforms: [.iOS(.v12)],
products: [
.library(
name: "swift-ndi",
targets: ["swift-ndi"])
],
dependencies: [],
targets: [
.target(name: "CiOSNDI", path: "Libraries"),
.target(
name: "swift-ndi",
dependencies: ["CiOSNDI"]),
.testTarget(
name: "swift-ndiTests",
dependencies: ["swift-ndi"]),
]
)
You can find the whole project at alessionossa/swift-ndi.
The only result at the moment are some warnings and the module CiOSNDI do not build:
I tried also .systemLibrary(name: "CiOSNDI", path: "Libraries/"), with this configuration: alessionossa/swift-ndi/tree/systemLibrary; but I get these errors:
NOTE
NDI_include is actually an alias/symbolic link to /Library/NDI Advanced SDK for Apple/include, while NDI_iOS_lib points to /Library/NDI Advanced SDK for Apple/lib/iOS.
I always cleaned build folder after changes to Package.swift.
UPDATE 10/01/2022: libndi_advanced_ios.a requires libc++.tbd. That can be easy linked in an app in Build Phases -> Link Binary With Libraries, but I don’t know how to link in a Swift Package.
Binary targets need to specified with .binary_target. See the docs and example here.
An example of a static library wrapped in an .xcframework looks like this from the file command:
$ file GoogleAppMeasurement.xcframework/ios-arm64_armv7/GoogleAppMeasurement.framework/GoogleAppMeasurement
GoogleAppMeasurement.xcframework/ios-arm64_armv7/GoogleAppMeasurement.framework/GoogleAppMeasurement: Mach-O universal binary with 2 architectures: [arm_v7:current ar archive] [arm64]
GoogleAppMeasurement.xcframework/ios-arm64_armv7/GoogleAppMeasurement.framework/GoogleAppMeasurement (for architecture armv7): current ar archive
GoogleAppMeasurement.xcframework/ios-arm64_armv7/GoogleAppMeasurement.framework/GoogleAppMeasurement (for architecture arm64): current ar archive
One way to create the .xcframework file is to use Firebase's ZipBuilder that creates a .xcframework files from static libraries that are specified with a CocoaPods podspec file.
I also needed to add the NDI SDK as a Swift package dependency in my app.
I found a couple of approaches that worked:
You can create an XCFramework bundle by extracting a thin arm64 library from the universal library:
lipo "/Library/NDI SDK for Apple/lib/iOS/libndi_ios.a" -thin arm64 -output "$STAGING_DIRECTORY/libndi.a"
Then create an XCFramework bundle:
xcodebuild -create-xcframework -library "$STAGING_DIRECTORY/libndi.a" -headers "/Library/NDI SDK for Apple/include" -output "$STAGING_DIRECTORY/Clibndi.xcframework"
I ended up not using this approach because hosting the XCFramework as a downloadable binary release on GitHub required me to make my repo public (see this issue).
Instead I am using a system library target, in my Package.swift:
targets: [
.target(
name: "WrapperLibrary",
dependencies: ["Clibndi"],
linkerSettings: [
.linkedFramework("Accelerate"),
.linkedFramework("VideoToolbox"),
.linkedLibrary("c++")
]),
.systemLibrary(name: "Clibndi")
]
Then, I have WrapperLibrary/Sources/Clibndi/module.modulemap that looks like:
module Clibndi {
header "/Library/NDI SDK for Apple/include/Processing.NDI.Lib.h"
link "ndi_ios"
export *
}
Finally, my application target (part of an Xcode project, not a Swift package) depends on WrapperLibrary, and I had to add "/Library/NDI SDK for Apple/lib/iOS" (including the quotation marks) to "Library Search Paths" in the "Build Settings" tab.
As an alternative to modifying the application target build settings, you could add a pkg-config file to a directory in your pkg-config search paths. For example, /usr/local/lib/pkgconfig/libndi_ios.pc:
NDI_SDK_ROOT=/Library/NDI\ SDK\ for\ Apple
Name: NDI SDK for iOS
Description: The NDI SDK for iOS
Version: 5.1.1
Cflags: -I${NDI_SDK_ROOT}/include
Libs: -L${NDI_SDK_ROOT}/lib/iOS -lndi_ios
Then use .systemLibrary(name: "Clibndi", pkgconfig: "libndi_ios") in your package manifest. I found this less convenient for users than just adding the setting to my application target, however.
Ideally you could add the NDI SDK's dependency library and frameworks to the pkg-config file as well (Libs: -L${NDI_SDK_ROOT}/lib/iOS -lndi_ios -lc++ -framework Accelerate -framework VideoToolbox), but it appears there is a bug in Swift's pkg-config parsing of -framework arguments, so I filed a bug: SR-15933.

Receiving error "include could not find load file" for cmake

Setting up swift-corelibs-xctest for Swift - Windows 10. When file CMakeLists.txt is called find_package is ran to look for FoundationConfig.cmake file
if(NOT CMAKE_SYSTEM_NAME STREQUAL Darwin)
find_package(dispatch CONFIG REQUIRED)
find_package(Foundation CONFIG REQUIRED)
endif()
FoundationConfig.cmake is found but error "include could not find load file: #Foundation_EXPORTS_FILE#"
I'm pretty sure this is due to fact that Foundation file is in a different directory. I only need clarification as to what # Foundation_EXPORTS_FILE# means. I have been unable to find any reference to _EXPORTS_FILE.
Believe I found part of what I was lookin for here.
https://gitlab.kitware.com/cmake/community/-/wikis/doc/cmake/ExportInterface
The other half of the problem was found here -
default search paths for CMake include() vs. find_package()
"include(#Foundation_EXPORTS_FILE#)" Was in reference to the two config files, which are not in the same location, also include() searches for files in CMAKE_MODULE_PATH --- message("Path- ${CMAKE_MODULE_PATH}")

CMake error: 'target is not built by this project' Clion Kotlin

I'm trying to load OpenCV Libraries in CMakeFile.txt but it always ends with this error:
CMake Error at CMakeLists.txt:21 (target_link_libraries):
Cannot specify link libraries for target "HelloWorld" which is not built by
this project.
I've searched on the Internet but have got no solution.
cmake_minimum_required(VERSION 3.8)
set(CMAKE_MODULE_PATH ${CMAKE_CURRENT_LIST_DIR}/KotlinCMakeModule)
project(untitled1 Kotlin)
find_package(OpenCV REQUIRED)
IF (OpenCV_FOUND)
include_directories(/usr/local/Cellar/opencv/3.4.0_1/include)
link_libraries(/usr/local/Cellar/opencv/3.4.0_1/lib)
ENDIF(OpenCV_FOUND)
konanc_executable(
NAME HelloWorld
SOURCES hello.kt
)
target_link_libraries(HelloWorld
/usr/local/Cellar/opencv/3.4.0_1/lib
)
Someone can help me? I think it's not working because on the use of konanc_executable instead of add_executable but I need to use Kotlin so I cannot use the add_executable command.

CMake OpenCV 3.0.0 and building executables and libraries in Ubuntu

I have OpenCV 3.0.0 installed in /usr/local/opencv-3.0.0
I am trying to construct a CMakeLists file to build a library against this OpenCV 3.0.0. The CMakeLists.txt is as follows:
cmake_minimum_required(VERSION 2.8)
project(STT_People_Tracker)
cmake_policy(SET CMP0016 NEW)
# compilation mode setup
#set(CMAKE_BUILD_TYPE Release)
set(CMAKE_BUILD_TYPE Debug)
# set OpenCV directories - CHANGE DEPENDING ON SYSTEM
set(OpenCV_PATH "/usr/local/opencv-3.0.0")
set(OpenCV_INCLUDE_DIRS "${OpenCV_PATH}/include")
set(OpenCV_LIBS "${OpenCV_PATH}/lib/")
# set environment variables
set(SOURCES_PATH "${CMAKE_SOURCE_DIR}/Sources")
set(INCLUDES_PATH "${SOURCES_PATH}/include")
if(CMAKE_BUILD_TYPE MATCHES Debug)
set(OUTPUT_PATH "../Debug")
message(STATUS "Compiling in DEBUG mode")
elseif(CMAKE_BUILD_TYPE MATCHES Release)
set(OUTPUT_PATH "../Release")
message(STATUS "Compiling in RELEASE mode")
endif()
include_directories(${INCLUDES_PATH})
include_directories(${OpenCV_INCLUDE_DIRS})
# compilation of executables
message(STATUS "configuring executables...")
add_executable(${OUTPUT_PATH}/mainTest ${SOURCES_PATH}/mainTest.cpp)
# compilation of libraries
message(STATUS "configuring libraries...")
add_library(${OUTPUT_PATH}/background_substractor ${SOURCES_PATH}/background_substractor.cpp)
# set linker options
link_directories(${OpenCV_LIBS})
target_link_libraries(${OUTPUT_PATH}/mainTest opencv_core opencv_highgui)
target_link_libraries(${OUTPUT_PATH}/background_substractor opencv_core opencv_highgui)
message(STATUS "cmake configuration complete")
It is a fairly simple Cmake file, however, I have the following problems/doubts:
1.-How can I know I am using OpenCV 3, and not other versions of OpenCV present in the system?
2.- When compiling the file background_substractor, its associated header file can not be located, although I have checked the path and it is correctly assigned in the set(INCLUDES_PATH "${SOURCES_PATH}/include"):
/home/alberto/STT_People_Tracking/Sources/background_substractor.cpp:3:36: fatal error: background_substractor.h: No such file or directory
#include "background_substractor.h"
^
compilation terminated.
make[2]: *** [CMakeFiles/../Debug/background_substractor.dir/Sources/background_substractor.cpp.o] Error 1
make[1]: *** [CMakeFiles/../Debug/background_substractor.dir/all] Error 2
make: *** [all] Error 2
3.- Finally, and if I comment the header file, I have problems linking:
Linking CXX static library lib../Debug/background_substractor.a
/usr/bin/ar: lib../Debug/background_substractor.a: No such file or directory
make[2]: *** [lib../Debug/background_substractor.a] Error 1
make[1]: *** [CMakeFiles/../Debug/background_substractor.dir/all] Error 2
make: *** [all] Error 2
I have tried everything: Specifying the include files in the add_executable() and add_library() commands, I have checked paths and they are ok, etc etc.
Could anyone more experienced with CMake, give me a little hand?
Thank you very much in advance,
Alberto
How can I know I am using OpenCV 3, and not other versions of OpenCV present in the system?
Your project should check that.
But usually projects just use find_package command for fill variables related to 3d-party library. This command perform all needed checks. In your case it could be
find_package(OpenCV 3 REQUIRED)
call, which fills OpenCV_LIBS and OpenCV_INCLUDE_DIRS variables automatically. This command, by default, search OpenCV installation in default paths, but you can adjust searching algorithm by using parameters to cmake (so, you needn't to change CMakeLists.txt when you build the project on other machine). E.g., this way
cmake -DOpenCV_DIR=/usr/local/opencv-3.0.0 <source-dir>
you can specify precise installation path of OpenCV.
When compiling the file background_substractor, its associated header file can not be located...
Cannot suggest anything aside from checking file existence
/home/alberto/STT_People_Tracking/Sources/include/background_substractor.h
But this also can be a result of the 3d issue(see below).
Finally, and if I comment the header file, I have problems linking...
Your usage of CMake targets is incorrect. Unlike to make targets, which usually are files, CMake targets are simple names. By default, name of library/executable target determines filename of the library/executable file, produced by this target, but this can be changed. Directory, where resulted file will be located, can be adjusted using CMAKE_<TYPE>_OUTPUT_DIRECTORY variables, where <TYPE> can be ARCHIVE, LIBRARY or RUNTIME depending on target type.
Correct CMake script would be:
cmake_minimum_required(VERSION 2.8)
project(STT_People_Tracker)
cmake_policy(SET CMP0016 NEW)
# compilation mode setup
#set(CMAKE_BUILD_TYPE Release)
set(CMAKE_BUILD_TYPE Debug)
# set OpenCV directories using find_package.
find_package(OpenCV 3 REQUIRED)
# set environment variables
set(SOURCES_PATH "${CMAKE_SOURCE_DIR}/Sources")
set(INCLUDES_PATH "${SOURCES_PATH}/include")
if(CMAKE_BUILD_TYPE MATCHES Debug)
set(OUTPUT_PATH "${CMAKE_BINARY_DIR}/Debug") # Use absolute path
message(STATUS "Compiling in DEBUG mode")
elseif(CMAKE_BUILD_TYPE MATCHES Release)
set(OUTPUT_PATH "${CMAKE_BINARY_DIR}/Release")
message(STATUS "Compiling in RELEASE mode")
endif()
# Set output directory for STATIC libraries and executables
set(CMAKE_ARCHIVE_OUTPUT_DIRECTORY ${OUTPUT_PATH})
set(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${OUTPUT_PATH})
include_directories(${INCLUDES_PATH})
include_directories(${OpenCV_INCLUDE_DIRS})
# compilation of executables
message(STATUS "configuring executables...")
add_executable(mainTest ${SOURCES_PATH}/mainTest.cpp) # Use simple name as a target
# compilation of libraries
message(STATUS "configuring libraries...")
add_library(background_substractor ${SOURCES_PATH}/background_substractor.cpp) # Use simple name as a target
# set linker options
# Command below is no-op: OpenCV libraries enumerated using absolute paths
# link_directories(${OpenCV_LINK_DIRECTORIES})
target_link_libraries(mainTest ${OpenCV_LIBS}) # Variable OpenCV_LIBS contains OpenCV libraries needed to link with
target_link_libraries(background_substractor ${OpenCV_LIBS})
message(STATUS "cmake configuration complete")

Resources