CUDA_ARCHITECTURES is empty for target "cmTC_28d80" - cmake

I made a new CUDA executable project in CLion and when it opened I got CMake error:
CUDA_ARCHITECTURES is empty for target "cmTC_908f4".
CMakeLists.txt:
cmake_minimum_required(VERSION 3.19)
project(test CUDA)
set(CMAKE_CUDA_STANDARD 14)
add_executable(test main.cu)
set_target_properties(
test
PROPERTIES
CUDA_SEPARABLE_COMPILATION ON)
I tried searching for this error on internet but not much success. I only tried to set
set_target_properties(test PROPERTIES CUDA_ARCHITECTURES "35;50;72")
but that didn't help.
At this point I don't know what to do anymore.

Although I am 9 months late to this, I think I actually solved it. I just stumbled across (what I believe to be) exactly the same problem. It occurred while trying to set up a new CUDA Project in CLion, and I got the same error.
I have now contacted the JetBrains support for CLion, and they pointed me to the solution of this problem.
If you have the same problem, you should see an auto-detected "x86" architecture under "Settings/Preferences > Build, Execution, Deployment > Toolchains > [the toolchain you are using for this project]". Simply manually select "amd64" instead (or, I suppose, whatever arch your system is running on), and then the CMake build should run fine, and a simple Hello World should also compile and run without problems.
Version Data:
CLion 2021.3.4
CMake 3.21.1 (bundled with CLion)
CUDA Toolkit 11.6
MSVC 2022 / Version 17.0
Windows 11 Pro

I wonder if the order matters, e.g. set Cuda architecture before compile features. My CMakeLists that works (and didn't before adding the CUDA_ARCHITECTURE line) is:
cmake_minimum_required(VERSION 3.16)
project(myTarget LANGUAGES CXX CUDA)
# Locate sources and headers for this project
include_directories(${PROJECT_SOURCE_DIR} ${PROJECT_SOURCE_DIR}/include /usr/local/cuda/include )
file(GLOB sources ${PROJECT_SOURCE_DIR}/*.cc ${PROJECT_SOURCE_DIR}/src/*.cc)
file(GLOB headers ${PROJECT_SOURCE_DIR}/*.h ${PROJECT_SOURCE_DIR}/include/*.h)
file(GLOB cuda_sources ${PROJECT_SOURCE_DIR}/src/*.cu)
# Add the executable, and link
add_executable(myTarget ${sources} ${cuda_sources} ${headers})
target_link_libraries(myTarget pthread z)
# Compile Info
set_target_properties(myTarget PROPERTIES CUDA_ARCHITECTURES "35;50;72")
target_compile_features(myTarget PUBLIC cxx_std_11)
target_compile_features(myTarget PUBLIC cuda_std_11)

Try setting your DCMAKE_CUDA_COMPILER as described here: https://www.jetbrains.com/help/clion/cuda-projects.html#set-nvcc - add your nvcc path in settings for CMake.
Remember to put full path to executable - not only bin folder

I got similar problem and was wondering what actually that CMAKE_CUDA_ARCHITECTURES stands for. It seems that it stands for particular architecture of NVidia cards for which the program shall be optimized or minimum architecture on which it shall run at all. I have found this link how these architecture numbers relate to the GPU used.
To cite most important codes:
Turing - CUDA 10+ - 75 CMAKE default
Ampere - CUDA 11.1+ - 80,86,87
Lovelace - CUDA 11.8+ - 89
Hopper - CUDA 12+ - 90
It seems that CMake at some point realized that 75 might be soon outdated but does not want to update it constantly. Thus you shall set it by your own or it warns you and as of now puts 75 as default.
If you will search NVidia, they tend to name these architectures e.g. "compute_50". Because architecture 35 is deprecated in CUDA11 it is not wise to follow CMake example to set
set_target_properties(myTarget PROPERTIES CUDA_ARCHITECTURES "35;50;72")
but use rather
set_target_properties(myTarget PROPERTIES CUDA_ARCHITECTURES "75") to silence the warning and retain the behavior.

Related

Modern CMake Cross Compiling to AArch64 with Sysroots

Consider the following example project_(CMakeLists.txt):
cmake_minimum_required(VERSION 3.1)
project(CCL LANGUAGES C CXX)
set(CMAKE_CXX_STANDARD 17)
set(CMAKE_CXX_STANDARD_REQUIRED ON)
set(CMAKE_C_STANDARD 99)
set(CMAKE_C_STANDARD_REQUIRED ON)
find_package(PkgConfig REQUIRED)
find_package(ZLIB)
find_package(PNG)
find_library(MATH_LIBRARY m)
pkg_search_module(OpenEXR OpenEXR)
add_executable(main main.cpp)
if (MATH_LIBRARY)
target_link_libraries(main PUBLIC ${MATH_LIBRARIES})
endif()
Main.cpp:
#include <iostream>
#include <cmath>
int main(void)
{
std::cout << "Hello, sin()" << std::sin(30) << std::endl;
return 0;
}
I want to compile this project with the following CMake toolchain
(aarch64-toolchain.cmake):
# Cross-compilation system information.
set(CMAKE_SYSTEM_NAME Linux)
set(CMAKE_SYSTEM_PROCESSOR aarch64)
# The sysroot contains all the libraries we might need to link against and
# possibly headers we need for compilation.
set(CMAKE_SYSROOT /var/lib/schroot/chroots/ubuntu-focal-arm64)
set(CMAKE_FIND_ROOT_PATH ${CMAKE_SYSROOT})
set(CMAKE_LIBRARY_ARCHITECTURE aarch64-linux-gnu)
# Install path when SYSROOT is read-only.
# set(CMAKE_STAGING_PREFIX aarch64-staging)
# Set the compilers for C, C++ and Fortran.
set(GCC_TRIPLE "aarch64-linux-gnu")
set(CMAKE_C_COMPILER ${GCC_TRIPLE}-gcc-10 CACHE FILEPATH "C compiler")
set(CMAKE_CXX_COMPILER ${GCC_TRIPLE}-g++-10 CACHE FILEPATH "C++ compiler")
set(CMAKE_Fortran_COMPILER ${GCC_TRIPLE}-gfortran CACHE FILEPATH "Fortran compiler")
# Automatically use the cross-wrapper for pkg-config when available.
set(PKG_CONFIG_EXECUTABLE aarch64-linux-gnu-pkg-config CACHE FILEPATH "pkg-config executable")
# Set the architecture-specific compiler flags.
set(ARCH_FLAGS "-mcpu=cortex-a53+crc+simd")
set(CMAKE_C_FLAGS_INIT ${ARCH_FLAGS})
set(CMAKE_CXX_FLAGS_INIT ${ARCH_FLAGS})
set(CMAKE_Fortran_FLAGS_INIT ${ARCH_FLAGS})
# Don't look for programs in the sysroot (these are ARM programs, they won't run
# on the build machine).
set(CMAKE_FIND_ROOT_PATH_MODE_PROGRAM NEVER)
# Only look for libraries, headers and packages in the sysroot, don't look on
# the build machine.
set(CMAKE_FIND_ROOT_PATH_MODE_LIBRARY ONLY)
set(CMAKE_FIND_ROOT_PATH_MODE_INCLUDE ONLY)
set(CMAKE_FIND_ROOT_PATH_MODE_PACKAGE ONLY)
set(CPACK_DEBIAN_PACKAGE_ARCHITECTURE arm64)
Where the sysroot (/var/lib/schroot/chroots/ubuntu-focal-arm64) was setup using:
name=ubuntu-focal
mk-sbuild --arch=arm64 --skip-proposed --skip-updates --skip-security --name=${name} focal
su - $USER
mk-sbuild --arch=arm64 --skip-proposed --skip-updates --skip-security --name=${name} focal
Configuration-wise, this works fine, however when I try to build this project
find_library 'correctly' finds the wrong libm.so library:
$ cmake -DCMAKE_TOOLCHAIN_FILE=../aarch-toolchain.cmake ..
$ make
Scanning dependencies of target main
[ 50%] Building CXX object CMakeFiles/main.dir/main.cpp.o
make[2]: *** No rule to make target '/var/lib/schroot/chroots/ubuntu-focal-arm64/usr/lib/aarch64-linux-gnu/libm.so', needed by 'main'. Stop.
make[1]: *** [CMakeFiles/Makefile2:76: CMakeFiles/main.dir/all] Error 2
make: *** [Makefile:84: all] Error 2
Looking into the sysroot itself, the library is correctly found, but obviously,
it is a symlink to a file local to the sysroot, not the host:
$ ls -hal /var/lib/schroot/chroots/ubuntu-focal-arm64/usr/lib/aarch64-linux-gnu/
lrwxrwxrwx 1 root root 32 Apr 14 2020 libm.so -> /lib/aarch64-linux-gnu/libm.so.6
It seems to me that CMake is picking up the wrong library (find_library should
really be using the compiler libraries first), so I guess that my toolchain-file
is written incorrectly somehow. How should it be changed to correctly find the
math library, without changing the sysroot or project itself?
(Also, please note that this is an example project to illustrate the problem. I still need to be able to search the sysroot for packages.)
Edits
As requested in the comments, the end state should be a proper aarch64 binary
("main"). Essentially, the build commands below should succeed both with and
without the toolchain, and should yield a functional binary (although, the
aarch64 one naturally only work inside the sysroot).
$ mkdir -p host-build && cd host-build && cmake .. && make
$ mkdir -p device-build && cd device-build && cmake -DCMAKE_TOOLCHAIN_FILE=../aarch64-toolchain.cmake .. && make
TLDR: There is no easy way, as far as I know.
Your toolchain file is fine, it's the symlinks that are bad and they should ideally be relative and not absolute if you wish to use it for building. Below I mention a few options and explain the issue. This is all based on my experience with cross-compiling. Perhaps someone knows more.
There isn't anything wrong with your toolchainfile. From my perspective it is configured correctly. This is an issue as you pointed out with the symlinks being relative to your created rootfs and not absolute to the host machine but they are presented as absolute.
IIRC there is not much you can do here.
I'll give you a few options that I know of from personal experience:
Forget cross-compiling and using QEMU chroot into the environment and build there. This is the easiest option.
Get all the required libraries on your host machine (outside of the sysroot) and compile using them - You just have to make sure that you have the exact same libraries as the target machine. Your toolchain file would be then reconfigured to look for libraries among the ones here.
EDIT: As #josch pointed out in the comments under his answer I should expand on this point to make it more clear to users. However because he already mentioned the most important steps to take when applying this, I will refer the reader to his answer. I will however provide a link to debians official HowTo regarding Multi-arch
The other option would mean fixing your projects CMakeLists to more adapt to the cross-compiling. This would require you to specify the absolute paths to the correct libraries. There is a drawback as you need to always point to the newest library. You could for example create another .cmake file that helps you configure the correct paths and because target_link_libraries() allows you to specify absolute paths, you could use the newly created custom targets.
The last option would be to fix the symlinks (ideally by making them relative). This is in my opinion the preferred way. In the end the rootfs that you will be using for building will be just that, i.e. used for building.
As far as I know (I might be wrong here) but the mks-build is just a debian tool that is originally used for packaging .deb files and as such wasn't made to be complimentary to CMake. And if it was then the debian team probably has the toolchain files you are looking for (i.e. I would look for cross-compiling and package guides regarding .deb packages - if they exist they will be included).
CMAKE_SYSROOT, CMAKE_FIND_ROOT_PATH only add a prefix to specific find_ commands/functions. They pretty much can't change anything about the target system or the linker behavior (which is the issue here). Which means they are correctly configured. It's the fake system that is wrongly configured.
You wrote to the debian-cross mailing list so I assume that your question is Debian specific? If so, maybe tag your question as such. Here is how you cross compile any Debian package for amd64 (aarch64) using sbuild:
sbuild --host=arm64 your_package.dsc
sbuild will take care of setting up your chroot as required and call the build tools with the correct arguments. You do not even need to create a special build chroot for that and can just re-use your existing chroots (sbuild will know what to do with them).
If instead, you just want to cross-compile some software using CMake on Debian, the process is as simple as installing a cross-compiler and pointing CMake to it:
$ sudo apt install g++-aarch64-linux-gnu
$ cmake -DCMAKE_CXX_COMPILER=aarch64-linux-gnu-g++ .
$ make VERBOSE=1
...
/usr/bin/aarch64-linux-gnu-g++ -rdynamic CMakeFiles/main.dir/main.cpp.o -o main
...
$ file main
main: ELF 64-bit LSB pie executable, ARM aarch64, version 1 (SYSV), dynamically linked, interpreter /lib/ld-linux-aarch64.so.1 ...
That's it. No need for a sysroot.
If you haven't set up arm64 as a foreign architecture on your system, you need to run this once:
dpkg --add-architecture arm64
apt-get update

Cmake cannot find wxWidgets on Windows

I have searched for this topic and found this and this, but it only seems to either pertain to building wxWidgets or do not contain an answer to my question.
I have built the static libs für wxWidgets on Windows successfully, but I am now struggling to correctly include the libraries to my project using Cmake. This is my CMakeLists.txt:
set(PROJECT_NAME wxapp)
project(${PROJECT_NAME})
cmake_minimum_required(VERSION 2.8)
set(SRC_LIST main.cpp app.cpp app.h frame.cpp frame.h)
add_executable(${PROJECT_NAME} WIN32 ${SRC_LIST})
find_package(wxWidgets REQUIRED net gl core base)
include(${wxWidgets_USE_FILE})
target_link_libraries(${PROJECT_NAME} ${wxWidgets_LIBRARIES})
set(wxWidgets_USE_LIBS ON)
set(wxWidgets_CONFIGURATION msw)
I have set the WXWIN path variable correctly. Yet, CMake throws an error with this configuration:
Could NOT find wxWidgets (missing: wxWidgets_LIBRARIES
wxWidgets_INCLUDE_DIRS net gl core base)
I have tried multiple suggestions, like using downloading prebuild dynamic libraries and adding them manually as suggested here, e.g.
set(wxWidgets_ROOT_DIR $ENV{WXWIN})
set(wxWidgets_LIBRARIES $ENV{WXWIN}/include)
set(wxWidgets_INCLUDE_DIR $ENV{WXWIN}/lib/vc14x_x64_dll)
include_directories(includes $ENV{WXWIN} $ENV{WXWIN}/include $ENV{WXWIN}/lib/vc14x_x64_dll)
link_directories($ENV{WXWIN} $ENV{WXWIN}/include $ENV{WXWIN}/lib/vc14x_x64_dll) # this seems to be a discouraged/deprecated method
but all to no avail.
WORKAROUND (at least it works for me):
I changed the find_package command from the suggested statement:
find_package(wxWidgets COMPONENTS gl core base OPTIONAL_COMPONENTS net)
to
find_package(wxWidgets 3.1 REQUIRED)
A user in this post had this included in his/her CMake file and out of deperation, I tried this and it actually worked. Seems like the configuration of CMake under certain unknown circumstances won't function correctly with the statement provided in the instructions. If I change the command to the new statement my static build as well as self- and precompiled dlls are flawlessly identifed by CMake.
I also cleared the CMake cache, inspired by this post. According to this post, there seems to be an issue with Windows and the CMake cache in some situations, but the reasons escape me. I could replicate the behaviour observed by the user there:
Under Windows, you have to point to the installation directory, e.g.
set(wxWidgets_ROOT_DIR "C:/wxWidgets-3.1.3") set(wxWidgets_LIB_DIR
"C:/wxWidgets-3.1.3/lib/vc14x_x64_dll")
But then the behavior is still strange. When i use CMake GUI (3.16,
latest), behavior is like this
delete cache (just to be consistent)
press 'configure' button
--> fail: CMake Error at C:/Program Files/CMake/share/cmake-3.16/Modules/FindPackageHandleStandardArgs.cmake:146
(message): Could NOT find wxWidgets (missing: wxWidgets_LIBRARIES
wxWidgets_INCLUDE_DIRS core base qa adv net html gl propgrid richtext)
press 'configure' button again
--> success
I also have observed some inconsistent behaviour of CMake within the IDEs CLion and CodeBlocks when clearing the cache and reloading the project.
So, exactly how the cache clearing plays into the resolution of my issue, I don't know. But if I merely clear the cache, reload my project and leave the CMake instruction at find_package(wxWidgets COMPONENTS gl core base OPTIONAL_COMPONENTS net), CMake won't find my installation despite the WXWIN path being set correctly.
If you know more about this, I am happy to be corrected.

CMake idiom for overcoming libstdc++ filesystem weirdness?

If you build C++14 code with G++ and libstdc++, there's a library named libstdc++fs, which is separate from the rest of libstdc++, and contains the code for std::experimental::filesystem. If you don't link against it, you'll get undefined references.
The "trick" I'm using for overcoming this right now is:
if ("${CMAKE_CXX_COMPILER_ID}" STREQUAL "GNU")
set(CXX_FILESYSTEM_LIBRARIES "stdc++fs")
endif()
and later:
target_link_libraries(my_target PUBLIC ${CXX_FILESYSTEM_LIBRARIES})
but - I don't like having to place this code in every project I work on. Is there a simpler or more standard idiom I could use? Some way this will all happen implicitly perhaps, with some CMake behind-the-scences magic?
tl;dr: Nothing right now, wait for a newer CMake version
As #Pedro graciously points out, this is a known problem, and there is an open issue about it at KitWare's GitLab site for CMake:
Portable linking for C++17 std::filesystem
If using CMAKE_CXX_STANDARD=17 and std::filesystem, GCC requires linking of an extra library: stdc++fs. ... If C++17 is enabled, would it be worth automatically linking to stdc++fs for GCC versions which require this? Likewise for any quirks in other compilers or libraries.
The KitWare issue is about C++17, for which apparently you still need the separate extra library (i.e. it's not just because of the "experimentality" in C++14). Hopefully we'll see some traction on this matter - but
Note: If you're experiencing this problem with C++17's std::filesystem, you're in luck - that code is built into libstdc++ beginning with GCC 9, so if you're using g++ 9 or later, and std::filesystem, you should no longer experience this problem.

Cuda CMake 3.10 CMakeLists.txt

I have a visual c++ project which creates a dll.
For this project I have a working CMakeLists.txt.
Now I created two cuda source files which complete the project and
with visual studio the build works fine.
I want to add the matching commands to my cmake file.
Can anyone tell me the basic commands I need to add?
I try to build a dll library where i use .cu and .cpp files....
The important part of my cmake file looks like:
# ----------------------------------------------------------------------------
# Set Cuda properties
# ----------------------------------------------------------------------------
enable_language(CUDA)
set(CUDA_SEPARABLE_COMPILATION ON)
set(CUDA_PROPAGATE_HOST_FLAGS OFF)
if (CMAKE_SIZEOF_VOID_P MATCHES 8)
set(CUDA_64_BIT_DEVICE_CODE_DEFAULT ON)
endif()
set(CUDA_NVCC_FLAGS "-gencode arch=compute_50,code=sm_50;-rdc=true;-use_fast_math")
message(STATUS "CUDA_PROPAGATE_HOST_FLAGS: ${CUDA_PROPAGATE_HOST_FLAGS}")
message(STATUS "CUDA_HOST_COMPILER: ${CUDA_HOST_COMPILER}")
message(STATUS "CUDA_NVCC_FLAGS: ${CUDA_NVCC_FLAGS}")
# ----------------------------------------------------------------------------
# Create shared library project
# ----------------------------------------------------------------------------
add_library(${LIB_NAME} SHARED ${HEADERS} ${SOURCES} ${CUDA_SOURCES})
set(CUDA_LIBRARIES "cudadevrt.lib;cudart.lib")
target_link_libraries(${LIB_NAME} ${CUDA_LIBRARIES})
But it doesn't compile the cuda files with the right flags.
Also in visual studio the preprocessor definitions are also in the cuda part of the properties....any suggestions?
I'll try to answer this question using the discussion from the comments and add some extra information.
First of all, there are two ways to enable CUDA support in CMake. One is the old FindCUDA module, and the other is the new built-in CUDA language support added in CMake 3.8, and explained here.
You can choose one or the other (but you'll probably want to use the built-in support for new projects), but then you have to stick with your choice.
To use built-in support you either add it to the project(...) statement or use:
enable_language(CUDA);
To use the old FindCUDA package, you would use:
find_package(CUDA);
Note that the two options use completely different variables for setup. To see what variables are supported by FindCUDA see this page, and for built-in CUDA support see this (don't forget that the <LANG> placeholder can be replaced by any language, which means that CUDA is also one of the available substitutions).
E.g. with FindCUDA you would use CUDA_NVCC_FLAGS to set the compiler flags manually, and with built-in language support you would use CMAKE_CUDA_FLAGS for the same purpose. As a rule of thumb: if the variable starts with CUDA_ it is a part of the FindCUDA package, and if it starts with CMAKE_, then it is part of built-in support.

How to cross compile CMake for ARM with CMake

In short I'm trying to cross compile CMake with CMake, and I don't think I'm linking libraries correctly. What I want to do may not be possible, but I'd at least like to know why it isn't possible if that's the case.
System: The host is a Linux box with a Cavium ARM9 CPU. It's currently running version 2.6.24.4 of the Linux kernel and Debian 5.0 (Lenny). My workstation is a Core i5 running Ubuntu 12.04 LTS (Precise Pangolin).
My overall goal is to get ROS running on the Linux box. I have to compile from source rather than use apt since Debian 6.0 (Squeeze) binaries require thumb support that the Cavium does not give, and not many of the needed packages are available for Debian 5.0 (Lenny). I'd made progress installing the various libraries needed, but when I got to step 1.3.1 and tried to run CMake, I got the error
CMake 2.8 or higher is required. You are running version 2.6.0
Next I tried to download and build CMake 2.8.8 on the Linux box itself, but it was too much for the system. When that failed, I downloaded the toolchain suggested on the manufacturer's website and used the cross-compiling guide at [www.cmake.org/Wiki/CMake_Cross_Compiling] to build the CMake executables. Here is my toolchain file:
# This one is important
SET(CMAKE_SYSTEM_NAME Linux)
# Specify the cross compiler
SET(CMAKE_C_COMPILER /pathto/crosstool-linux-gcc-4.5.2-gclibc-2.9-oabi/arm-unknown-linux-gnu/bin/arm-unknown-linux-gnu-gcc)
SET(CMAKE_CXX_COMPILER /pathto/crosstool-linux-gcc-4.5.2-gclibc-2.9-oabi/arm-unknown-linux-gnu/bin/arm-unknown-linux-gnu-g++)
# Where is the target environment
SET(CMAKE_FIND_ROOT_PATH /pathto/crosstool-linux-gcc-4.5.2-gclibc-2.9-oabi/arm-unknown-linux-gnu /pathto/crosstool-linux-gcc-4.5.2-gclibc-2.9-oabi/arm-unknown-linux-gnu/arm-unknown-linux-gnu)
# Search for programs in the build host directories
SET(CMAKE_FIND_ROOT_PATH_MODE_PROGRAM NEVER)
# For libraries and headers in the target directories
SET(CMAKE_FIND_ROOT_PATH_MODE_LIBRARY ONLY)
SET(CMAKE_FIND_ROOT_PATH_MODE_INCLUDE ONLY)
However, use of the binary on the Linux box gives the error
cmake: /usr/lib/libstdc++.so.6: version `GLIBCXX_3.4.14' not found (required by cmake)
Sure enough, the library is not there:
prompt# strings /usr/lib/libstdc++.so.6 | grep GLIBC
GLIBCXX_3.4
GLIBCXX_3.4.1
GLIBCXX_3.4.2
GLIBCXX_3.4.3
GLIBCXX_3.4.4
GLIBCXX_3.4.5
GLIBCXX_3.4.6
GLIBCXX_3.4.7
GLIBCXX_3.4.8
GLIBCXX_3.4.9
GLIBCXX_3.4.10
GLIBC_2.3
GLIBC_2.0
GLIBC_2.3.2
GLIBC_2.1
GLIBC_2.1.3
GLIBC_2.2
GLIBCXX_FORCE_NEW
GLIBCXX_DEBUG_MESSAGE_LENGTH
I've never cross-compiled before, but I can see one of two scenarios happening: either the binary got created with a link to a higher version of glibcxx on the host machine or the manufacturer's toolchain is more modern than their image. I don't know how to check which is happening or if something else is happening that I don't know about.
My last effort involved trying to statically cross-compile CMake to hopefully get rid of the linking error with
cmake -DCMAKE_TOOLCHAIN_FILE=../toolchain-technologic.cmake -DBUILD_SHARED_LIBS=OFF -DCMAKE_BUILD_TYPE=Release -DCMAKE_EXE_LINKER_FLAGS_RELEASE="-static" ..
I got build errors, and that binary didn't work either. I got:
FATAL: kernel too old
Segmentation fault
I'd try installing glibcxx 3.4.14 on the Linux box, but it doesn't look like it's available for this processor.
I've tried searching for CMake dependencies or system requirements and can't find anything. I've also searched on how to build CMake, but most searches turn up how to build other things with CMake rather than building CMake itself.
I do cross-compile a lot for ARM9 devices using CMake, and indeed this looks like you're not linking to the same libs you have on your target device. You shouldn't need to build CMake yourself to get this done, since it does have good support for cross-compiling since version 2.6. Just make sure you set the CMAKE_FIND_ROOT_PATH variable to a path where you have an exact copy of the root filesystem you have on your target device (with libraries and binaries pre-compiled for the target processor). That should solve your problems.
As a sidenote, I like to use crosstool-ng for building my cross-compilers. It is a really nice tool which helps you to build them from scratch, so I try to match the compiler version and glibc to the ones originally used to build the root filesystem (I usually start with a ready made root filesystem from ARMedslack, since I use Slackware for my development box and ARMedslack for my ARM targets).