I know how to link different libraries based on whether build configuration is Debug or Release. I use:
foreach(dep ${DEPENDENCIES})
target_link_libraries (${PROJECT_NAME}
debug ${dep}_d
optimized ${dep}
)
endforeach(dep)
CMake by default create 4 build configurations in VS2010 (Debug, Release, RelWithDebugInfo, MinSizeRelease). But how to define taget link libraries for RelWithDebugInfo configuration?
Bakcground:
I use only Debug, Release and RelWithDebugInfo. My debug libraries have suffix _d and others have no suffix. So output files from Release and RelWithDebugInfo are the same. Sometimes when I build RelWithDebugInfo and then Release some output files are not overwritten and thus bad ones are loaded and program crashes. I want to solve this problem by adding some other suffix to RelWithDebugInfo configuration.
I have found the solution. It is impossible to do via target_link_librearies but it can be done by setting linker flags:
set(DEBUG_DEP)
set(RWD_DEP)
set(RELEASE_DEP)
foreach(dep ${DEPENDENCIES})
set(RWD_DEP ${RWD_DEP} ${dep}_rwd)
set(DEBUG_DEP ${DEBUG_DEP} ${dep}_d)
set(RELEASE_DEP ${RELEASE_DEP} ${dep})
endforeach(dep)
set(CMAKE_SHARED_LINKER_FLAGS_DEBUG ${CMAKE_SHARED_LINKER_FLAGS_DEBUG} " /LIBPATH:" ${DEBUG_DEP})
set(CMAKE_SHARED_LINKER_FLAGS_RELEASE ${CMAKE_SHARED_LINKER_FLAGS_RELEASE} " /LIBPATH:" ${RELEASE_DEP})
set(CMAKE_SHARED_LINKER_FLAGS_RELWITHDEBINFO ${CMAKE_SHARED_LINKER_FLAGS_RELWITHDEBINFO}" /LIBPATH:" ${RWD_DEP})
Related
I need to build csparse library for an Android project. The project supports Make build system.
I am not familiar with use of NDK for Make build. I have used Androids CMake toolchain for building CMake based projects.
I am looking for pointers to usage of NDK for building C++ projects based on Make. I do not want to manually write a CMakeLists.txt for building the project with CMake toolchain because there are too many source files in the csparse project!
Any help is appreciated!
https://developer.android.com/ndk/guides/other_build_systems covers using the NDK with build systems other than ndk-build and CMake. The last section explicitly covers traditional make projects.
OK, It wasn't so difficult. It seems CSparse is a self-contained and does not depend on other linear-algebra libraries such as CHOLMOD, BLAS, LAPACK, Metis... etc
Here is the CMakeLists.txt file from my Android project :
cmake_minimum_required(VERSION 3.4.1)
include_directories(
${CMAKE_CURRENT_SOURCE_DIR}/include/CSparse/Source
)
add_library( # Sets the name of the library.
csparse-lib
# Sets the library as a shared library.
SHARED
# Provides a relative path to your source file(s).
include/CSparse/Source/cs_add.c
include/CSparse/Source/cs_amd.c
include/CSparse/Source/cs_chol.c
include/CSparse/Source/cs_cholsol.c
include/CSparse/Source/cs_compress.c
include/CSparse/Source/cs_counts.c
include/CSparse/Source/cs_cumsum.c
include/CSparse/Source/cs_dfs.c
include/CSparse/Source/cs_dmperm.c
include/CSparse/Source/cs_droptol.c
include/CSparse/Source/cs_dropzeros.c
include/CSparse/Source/cs_dupl.c
include/CSparse/Source/cs_entry.c
include/CSparse/Source/cs_ereach.c
include/CSparse/Source/cs_etree.c
include/CSparse/Source/cs_fkeep.c
include/CSparse/Source/cs_gaxpy.c
include/CSparse/Source/cs_happly.c
include/CSparse/Source/cs_house.c
include/CSparse/Source/cs_ipvec.c
include/CSparse/Source/cs_leaf.c
include/CSparse/Source/cs_load.c
include/CSparse/Source/cs_lsolve.c
include/CSparse/Source/cs_ltsolve.c
include/CSparse/Source/cs_lu.c
include/CSparse/Source/cs_lusol.c
include/CSparse/Source/cs_malloc.c
include/CSparse/Source/cs_maxtrans.c
include/CSparse/Source/cs_multiply.c
include/CSparse/Source/cs_norm.c
include/CSparse/Source/cs_permute.c
include/CSparse/Source/cs_pinv.c
include/CSparse/Source/cs_post.c
include/CSparse/Source/cs_print.c
include/CSparse/Source/cs_pvec.c
include/CSparse/Source/cs_qr.c
include/CSparse/Source/cs_qrsol.c
include/CSparse/Source/cs_randperm.c
include/CSparse/Source/cs_reach.c
include/CSparse/Source/cs_scatter.c
include/CSparse/Source/cs_scc.c
include/CSparse/Source/cs_schol.c
include/CSparse/Source/cs_spsolve.c
include/CSparse/Source/cs_sqr.c
include/CSparse/Source/cs_symperm.c
include/CSparse/Source/cs_tdfs.c
include/CSparse/Source/cs_transpose.c
include/CSparse/Source/cs_updown.c
include/CSparse/Source/cs_usolve.c
include/CSparse/Source/cs_util.c
include/CSparse/Source/cs_utsolve.c
)
add_library(native-lib SHARED native-lib.cpp)
find_library( # Sets the name of the path variable.
log-lib
log)
target_link_libraries( # Specifies the target library.
native-lib
# Links the target library to the log library
# included in the NDK.
${log-lib}
csparse-lib
)
I hope this answer helps others.
Problem is quite simple. I have multi platform project (Windows/Mac OS).
Now in case of Mac OS I need to enable "Hardened runtime" in capabilities section of my bundle (it is launchd daemon).
I wish my Xcode project is generated by cmake (I don't want to maintain multiple project files).
If I can overcome this problem by modifying build process (for example by adding some flags to xcodebuidl command) it should be fine, but I prefer when everything is defined in CMakeLists.txt files.
You can use the property XCODE_ATTRIBUTE_ENABLE_HARDENED_RUNTIME, which is a boolean.
Set that property on your macOS target, e.g.
set_property(TARGET target PROPERTY XCODE_ATTRIBUTE_ENABLE_HARDENED_RUNTIME YES)
Or if you provide more properties for the target it might look like this:
set_target_properties(target PROPERTIES
MACOSX_BUNDLE TRUE
MACOSX_BUNDLE_BUNDLE_NAME "yourTargetName"
MACOSX_RPATH TRUE
MACOSX_FRAMEWORK_IDENTIFIER com.host.target
XCODE_ATTRIBUTE_LD_RUNPATH_SEARCH_PATHS "#loader_path/Libraries"
RESOURCE "${RESOURCE_FILES}"
XCODE_ATTRIBUTE_ENABLE_HARDENED_RUNTIME YES
)
I have an Android Studio project which depends on a native shared library. I have created a cmake file to compile the library and I have added a soft link to the shared library inside the android project (in src/main/jniLibs/armeabi). That way when the android project is built, the shared library is included in the package.
Here is the relevant part of build.gradle:
android {
...
externalNativeBuild {
cmake {
path "../cpp/CMakeLists.txt"
}
}
}
The problem is that gradle tries to open the shared library before invoking the instructions to build it.
Information:Gradle tasks [:app:assembleDebug]
Error:Could not list contents of 'app/src/main/jniLibs/armeabi/libfoo.so'. Couldn't follow symbolic link.
How can I invoke the cmake from inside the project and include the library in the project at the same time?
--
EDIT
In the cmake the shared library is built with ExternalProject_Add. Unfortunately gradle doesn't see that target, nor does it see imported shared libraries as targets. So this does not work:
add_library(libfoo SHARED IMPORTED GLOBAL)
add_dependencies(libfoo libactual)
I tried to invoke building the particular target with a gradle config:
defaultConfig {
...
externalNativeBuild {
cmake {
targets "libfoo"
}
}
}
But gradle still doesn't see it and fails with:
Unexpected native build target libfoo. Valid values are:
The valid values are basically an empty list.
Currently I work around this by creating a fictional executable depending on the library.
add_executable(libfoo a.c)
add_dependencies(libfoo libactual)
In my case, I added a new CMake target, but having none was cached somehow (by CMake or Gradle).
Simply close Android Studio, remove the entire build or .build directory, then open Android Studio and build again.
Note that sub-projects have their own separate build directory.
So, you may need to search for the word build, and after ensuring found result is not required, remove them too.
If still not fixed, remember that CMake has it's own separate cache files, which normallay are inside said directories unless you run CMake directly (outside of Android Studio).
I have some huge project that is being compiled in CMake.
It is developed for quite a long time, have 8000+ source/header files (over 500Mbytes, over 500 CMakefile.txt files).
They use directory structure like this
PROJECT_NAME
src
/ subdir_name
/ other_dir_name
/ some_different_dir
/ MY_SPECIFIC_DIR <---
/ yet_another_dir
build
and build it out-source, like this:
name#host:~/PROJECT_NAME/build> cmake ../src
name#host:~/PROJECT_NAME/build> make all
then it's build as one BIG binary (details are not important).
I cannot touch anything else, just content of MY_SPECIFIC_DIR - it's source and CMake files.
So, I have source code in MY_SPECIFIC_DIR tweak CMakefile.txt files somehow and would like to build it like this:
name#host:~/PROJECT_NAME/build_specific> cmake ../src/MY_SPECIFIC_DIR
name#host:~/PROJECT_NAME/build_specific> make all
This should build things in MY_SPECIFIC_DIR into single binary with some few links to other subprojects. But also (obviously) don't change anything about how whole project is compiled.
My question is:
Is my desired setup
posible
using CMake?
Can I somehow test in CMakeFile.txt that it is root project and build it in different way then when it is builded as a whole?
Unless, I have to resort to different means and use standard make for this.
I don't know CMake so I'm hoping for YES/NO anwer, preferable even for technique how to achieve this. And then learn the CMake and do it.
Also, I must use CMake version 2.6.
Thanks
Basic concept is to use
if (CMAKE_SOURCE_DIR STREQUAL CMAKE_CURRENT_SOURCE_DIR)
... code for stand-alone app
else()
... what was in this file before
endif()
I am compiling my project in the release mode in VC++.
I have a .def file where i have declared the setLog and now i
am getting following error
Linking...
Creating library Release/HKL.lib and object Release/HKL.exp
HKL_libinterface.obj : error LNK2001: unresolved external symbol _SCTP_setLog#8
Please help me on the above to fix the problem.
Thanks
It sounds to me like you have a lib file configured in your debug build that is not in the release build. Your setLog() function does not seem to be the function the linker is complaining about - it sounds like it's not finding a function called SCTP_setLog().
Look in the list of libraries you have configured in your project's debug configuration and make sure they are also configured in the release configuration.
If this compiles in Debug mode the most possible reason is that somehow the code where this function is implemented is not included into build - for example, the cpp file where it is implemented has "Excluded from build" set.
As sharptooth mentioned, you most likely are not compiling the above function in your release build. In addition to looking for 'Excluded from build', check if you have any defines set (or not set) that would exclude the missing function from your release build.