使用cmake交叉编译多个库和应用程序

使用cmake交叉编译多个库和应用程序,c,cmake,C,Cmake,我在交叉编译现有的大型代码库时遇到了cmake问题。我们当前的构建系统使用了一个专有的IDE,这导致了大量的问题——所以我们正在尝试转移 我已经把它提炼成我能做的最简单的例子 注意:当我不在cmake中使用toolchain选项时,这一切都起作用。只要使用本机工具链,我就可以编译并运行它 我目前不怀疑cmake的工具链文件存在问题。我用它来编译OpenCV——用一些黑客的OpenCV 我在尝试交叉编译时遇到的错误是: -- The C compiler identification is GNU

我在交叉编译现有的大型代码库时遇到了cmake问题。我们当前的构建系统使用了一个专有的IDE,这导致了大量的问题——所以我们正在尝试转移

我已经把它提炼成我能做的最简单的例子

注意:当我不在cmake中使用toolchain选项时,这一切都起作用。只要使用本机工具链,我就可以编译并运行它

我目前不怀疑cmake的工具链文件存在问题。我用它来编译OpenCV——用一些黑客的OpenCV

我在尝试交叉编译时遇到的错误是:

-- The C compiler identification is GNU 4.8.3
-- The CXX compiler identification is GNU 4.8.3
-- Check for working C compiler: /opt/qnx650/host/linux/x86/usr/bin/ntox86-gcc
-- Check for working C compiler: /opt/qnx650/host/linux/x86/usr/bin/ntox86-gcc -- works
-- Detecting C compiler ABI info
-- Detecting C compiler ABI info - done
-- Check for working CXX compiler: /opt/qnx650/host/linux/x86/usr/bin/ntox86-g++
-- Check for working CXX compiler: /opt/qnx650/host/linux/x86/usr/bin/ntox86-g++ -- works
-- Detecting CXX compiler ABI info
-- Detecting CXX compiler ABI info - done
-- Configuring done
-- Generating done
-- Build files have been written to: /home/MY_USER/Desktop/test_app/build-test_app
Scanning dependencies of target liba
[ 25%] Building C object libs/liba/CMakeFiles/liba.dir/liba.c.o
Linking C shared library libliba.so
[ 25%] Built target liba
Scanning dependencies of target libb
[ 50%] Building C object libs/libb/CMakeFiles/libb.dir/libb.c.o
make[2]: *** No rule to make target `libs/liba/liba.a', needed by `libs/libb/liblibb.so.1.0.0'.  Stop.
make[1]: *** [libs/libb/CMakeFiles/libb.dir/all] Error 2
make: *** [all] Error 2
这就像是在寻找库的静态版本,但我已将其配置为在调用cmake时使用共享对象:

cmake -DBUILD_SHARED_LIBS=1 ..
我已经包括了下面测试项目中的所有文件。这与我试图编译更大的项目时遇到的问题相同

项目结构:

test_app
├── app
│   ├── appa
│   │   ├── appa.c
│   │   └── CMakeLists.txt
│   └── CMakeLists.txt
├── CMakeLists.txt
├── include
│   ├── liba
│   │   └── liba.h
│   ├── libb
│   │   └── libb.h
│   └── libc
│       └── libc.h
└── libs
    ├── CMakeLists.txt
    ├── liba
    │   ├── CMakeLists.txt
    │   └── liba.c
    ├── libb
    │   ├── CMakeLists.txt
    │   └── libb.c
    └── libc
        ├── CMakeLists.txt
        └── libc.c
顶级CMakeLists.txt

project(test)

cmake_minimum_required(VERSION 2.8)

set(CMAKE_INSTALL_PREFIX "/opt/test")
set(INSTALL_PERMISSIONS OWNER_READ OWNER_EXECUTE GROUP_READ GROUP_EXECUTE WORLD_EXECUTE)

set(TEST_VERSION 1.0.0)
set(TEST_MAJOR_VERSION 1)

set(TEST_GLOBAL_INCLUDES
  $<BUILD_INTERFACE:${CROSS_TARGET}/usr/pkg/include>
  $<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/include>
)

set(TEST_GLOBAL_LIB_PATHS
  $<BUILD_INTERFACE:${CROSS_TARGET}/usr/pkg/include>
  $<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/include>
)

add_subdirectory(libs)
add_subdirectory(app)
add_subdirectory(appa)
project(appa)

add_executable(appa appa.c)

target_include_directories(appa PUBLIC ${TEST_GLOBAL_INCLUDES})
target_link_libraries(appa libc)

# Set version information
set_target_properties(appa PROPERTIES
    VERSION ${TEST_VERSION}
)

# set install destination and permissions
install(
    TARGETS appa
    RUNTIME DESTINATION lib
    PERMISSIONS ${INSTALL_PERMISSIONS}
)
add_subdirectory(liba)
add_subdirectory(libb)
add_subdirectory(libc)
project(libliba)

add_library(liba liba.c)

target_include_directories(liba PUBLIC ${TEST_GLOBAL_INCLUDES})

# Set version information
set_target_properties(liba PROPERTIES
    VERSION ${TEST_VERSION}
    SOVERSION ${TEST_MAJOR_VERSION}
)

# set install destination and permissions
install(
    TARGETS liba
    LIBRARY DESTINATION lib
    ARCHIVE DESTINATION lib
    RUNTIME DESTINATION lib
    PERMISSIONS ${INSTALL_PERMISSIONS}
)
project(liblibb)

add_library(libb libb.c)

target_include_directories(liba PUBLIC ${TEST_GLOBAL_INCLUDES})

# Set version information
set_target_properties(libb PROPERTIES
    VERSION ${TEST_VERSION}
    SOVERSION ${TEST_MAJOR_VERSION}
)

target_link_libraries(libb liba)

# set install destination and permissions
install(
    TARGETS libb
    LIBRARY DESTINATION lib
    ARCHIVE DESTINATION lib
    RUNTIME DESTINATION lib
    PERMISSIONS ${INSTALL_PERMISSIONS}
)
project(liblibc)

add_library(libc libc.c)

target_include_directories(libc PUBLIC ${TEST_GLOBAL_INCLUDES})

# Set version information
set_target_properties(libc PROPERTIES
    VERSION ${TEST_VERSION}
    SOVERSION ${TEST_MAJOR_VERSION}
)

target_link_libraries(libc libb)

# set install destination and permissions
install(
    TARGETS libc
    LIBRARY DESTINATION lib
    ARCHIVE DESTINATION lib
    RUNTIME DESTINATION lib
    PERMISSIONS ${INSTALL_PERMISSIONS}
)
app/appa/CMakeLists.txt

project(test)

cmake_minimum_required(VERSION 2.8)

set(CMAKE_INSTALL_PREFIX "/opt/test")
set(INSTALL_PERMISSIONS OWNER_READ OWNER_EXECUTE GROUP_READ GROUP_EXECUTE WORLD_EXECUTE)

set(TEST_VERSION 1.0.0)
set(TEST_MAJOR_VERSION 1)

set(TEST_GLOBAL_INCLUDES
  $<BUILD_INTERFACE:${CROSS_TARGET}/usr/pkg/include>
  $<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/include>
)

set(TEST_GLOBAL_LIB_PATHS
  $<BUILD_INTERFACE:${CROSS_TARGET}/usr/pkg/include>
  $<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/include>
)

add_subdirectory(libs)
add_subdirectory(app)
add_subdirectory(appa)
project(appa)

add_executable(appa appa.c)

target_include_directories(appa PUBLIC ${TEST_GLOBAL_INCLUDES})
target_link_libraries(appa libc)

# Set version information
set_target_properties(appa PROPERTIES
    VERSION ${TEST_VERSION}
)

# set install destination and permissions
install(
    TARGETS appa
    RUNTIME DESTINATION lib
    PERMISSIONS ${INSTALL_PERMISSIONS}
)
add_subdirectory(liba)
add_subdirectory(libb)
add_subdirectory(libc)
project(libliba)

add_library(liba liba.c)

target_include_directories(liba PUBLIC ${TEST_GLOBAL_INCLUDES})

# Set version information
set_target_properties(liba PROPERTIES
    VERSION ${TEST_VERSION}
    SOVERSION ${TEST_MAJOR_VERSION}
)

# set install destination and permissions
install(
    TARGETS liba
    LIBRARY DESTINATION lib
    ARCHIVE DESTINATION lib
    RUNTIME DESTINATION lib
    PERMISSIONS ${INSTALL_PERMISSIONS}
)
project(liblibb)

add_library(libb libb.c)

target_include_directories(liba PUBLIC ${TEST_GLOBAL_INCLUDES})

# Set version information
set_target_properties(libb PROPERTIES
    VERSION ${TEST_VERSION}
    SOVERSION ${TEST_MAJOR_VERSION}
)

target_link_libraries(libb liba)

# set install destination and permissions
install(
    TARGETS libb
    LIBRARY DESTINATION lib
    ARCHIVE DESTINATION lib
    RUNTIME DESTINATION lib
    PERMISSIONS ${INSTALL_PERMISSIONS}
)
project(liblibc)

add_library(libc libc.c)

target_include_directories(libc PUBLIC ${TEST_GLOBAL_INCLUDES})

# Set version information
set_target_properties(libc PROPERTIES
    VERSION ${TEST_VERSION}
    SOVERSION ${TEST_MAJOR_VERSION}
)

target_link_libraries(libc libb)

# set install destination and permissions
install(
    TARGETS libc
    LIBRARY DESTINATION lib
    ARCHIVE DESTINATION lib
    RUNTIME DESTINATION lib
    PERMISSIONS ${INSTALL_PERMISSIONS}
)
app/appa/appa.c

#include <stdlib.h>
#include <stdio.h>

#include <libc/libc.h>

int main(int argc, char **argv)
{
    printf("Hello world: %d\n", libc_function(2));
    return EXIT_SUCCESS;
}
include/libb/libb.h

#pragma once

int libb_function(int a);
include/libc/libc.h

#pragma once

int libc_function(int a);
libs/CMakeLists.txt

project(test)

cmake_minimum_required(VERSION 2.8)

set(CMAKE_INSTALL_PREFIX "/opt/test")
set(INSTALL_PERMISSIONS OWNER_READ OWNER_EXECUTE GROUP_READ GROUP_EXECUTE WORLD_EXECUTE)

set(TEST_VERSION 1.0.0)
set(TEST_MAJOR_VERSION 1)

set(TEST_GLOBAL_INCLUDES
  $<BUILD_INTERFACE:${CROSS_TARGET}/usr/pkg/include>
  $<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/include>
)

set(TEST_GLOBAL_LIB_PATHS
  $<BUILD_INTERFACE:${CROSS_TARGET}/usr/pkg/include>
  $<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/include>
)

add_subdirectory(libs)
add_subdirectory(app)
add_subdirectory(appa)
project(appa)

add_executable(appa appa.c)

target_include_directories(appa PUBLIC ${TEST_GLOBAL_INCLUDES})
target_link_libraries(appa libc)

# Set version information
set_target_properties(appa PROPERTIES
    VERSION ${TEST_VERSION}
)

# set install destination and permissions
install(
    TARGETS appa
    RUNTIME DESTINATION lib
    PERMISSIONS ${INSTALL_PERMISSIONS}
)
add_subdirectory(liba)
add_subdirectory(libb)
add_subdirectory(libc)
project(libliba)

add_library(liba liba.c)

target_include_directories(liba PUBLIC ${TEST_GLOBAL_INCLUDES})

# Set version information
set_target_properties(liba PROPERTIES
    VERSION ${TEST_VERSION}
    SOVERSION ${TEST_MAJOR_VERSION}
)

# set install destination and permissions
install(
    TARGETS liba
    LIBRARY DESTINATION lib
    ARCHIVE DESTINATION lib
    RUNTIME DESTINATION lib
    PERMISSIONS ${INSTALL_PERMISSIONS}
)
project(liblibb)

add_library(libb libb.c)

target_include_directories(liba PUBLIC ${TEST_GLOBAL_INCLUDES})

# Set version information
set_target_properties(libb PROPERTIES
    VERSION ${TEST_VERSION}
    SOVERSION ${TEST_MAJOR_VERSION}
)

target_link_libraries(libb liba)

# set install destination and permissions
install(
    TARGETS libb
    LIBRARY DESTINATION lib
    ARCHIVE DESTINATION lib
    RUNTIME DESTINATION lib
    PERMISSIONS ${INSTALL_PERMISSIONS}
)
project(liblibc)

add_library(libc libc.c)

target_include_directories(libc PUBLIC ${TEST_GLOBAL_INCLUDES})

# Set version information
set_target_properties(libc PROPERTIES
    VERSION ${TEST_VERSION}
    SOVERSION ${TEST_MAJOR_VERSION}
)

target_link_libraries(libc libb)

# set install destination and permissions
install(
    TARGETS libc
    LIBRARY DESTINATION lib
    ARCHIVE DESTINATION lib
    RUNTIME DESTINATION lib
    PERMISSIONS ${INSTALL_PERMISSIONS}
)
libs/liba/CMakeLists.txt

project(test)

cmake_minimum_required(VERSION 2.8)

set(CMAKE_INSTALL_PREFIX "/opt/test")
set(INSTALL_PERMISSIONS OWNER_READ OWNER_EXECUTE GROUP_READ GROUP_EXECUTE WORLD_EXECUTE)

set(TEST_VERSION 1.0.0)
set(TEST_MAJOR_VERSION 1)

set(TEST_GLOBAL_INCLUDES
  $<BUILD_INTERFACE:${CROSS_TARGET}/usr/pkg/include>
  $<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/include>
)

set(TEST_GLOBAL_LIB_PATHS
  $<BUILD_INTERFACE:${CROSS_TARGET}/usr/pkg/include>
  $<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/include>
)

add_subdirectory(libs)
add_subdirectory(app)
add_subdirectory(appa)
project(appa)

add_executable(appa appa.c)

target_include_directories(appa PUBLIC ${TEST_GLOBAL_INCLUDES})
target_link_libraries(appa libc)

# Set version information
set_target_properties(appa PROPERTIES
    VERSION ${TEST_VERSION}
)

# set install destination and permissions
install(
    TARGETS appa
    RUNTIME DESTINATION lib
    PERMISSIONS ${INSTALL_PERMISSIONS}
)
add_subdirectory(liba)
add_subdirectory(libb)
add_subdirectory(libc)
project(libliba)

add_library(liba liba.c)

target_include_directories(liba PUBLIC ${TEST_GLOBAL_INCLUDES})

# Set version information
set_target_properties(liba PROPERTIES
    VERSION ${TEST_VERSION}
    SOVERSION ${TEST_MAJOR_VERSION}
)

# set install destination and permissions
install(
    TARGETS liba
    LIBRARY DESTINATION lib
    ARCHIVE DESTINATION lib
    RUNTIME DESTINATION lib
    PERMISSIONS ${INSTALL_PERMISSIONS}
)
project(liblibb)

add_library(libb libb.c)

target_include_directories(liba PUBLIC ${TEST_GLOBAL_INCLUDES})

# Set version information
set_target_properties(libb PROPERTIES
    VERSION ${TEST_VERSION}
    SOVERSION ${TEST_MAJOR_VERSION}
)

target_link_libraries(libb liba)

# set install destination and permissions
install(
    TARGETS libb
    LIBRARY DESTINATION lib
    ARCHIVE DESTINATION lib
    RUNTIME DESTINATION lib
    PERMISSIONS ${INSTALL_PERMISSIONS}
)
project(liblibc)

add_library(libc libc.c)

target_include_directories(libc PUBLIC ${TEST_GLOBAL_INCLUDES})

# Set version information
set_target_properties(libc PROPERTIES
    VERSION ${TEST_VERSION}
    SOVERSION ${TEST_MAJOR_VERSION}
)

target_link_libraries(libc libb)

# set install destination and permissions
install(
    TARGETS libc
    LIBRARY DESTINATION lib
    ARCHIVE DESTINATION lib
    RUNTIME DESTINATION lib
    PERMISSIONS ${INSTALL_PERMISSIONS}
)
libs/liba/liba.c

#include <liba/liba.h>

int liba_function(int a)
{
    return a * a;
}
libs/libb/libb.c

#include <liba/liba.h>
#include <libb/libb.h>

int libb_function(int a)
{
    return liba_function(a) * liba_function(a);
}
libs/libc/libc.c

#include <libb/libb.h>
#include <libc/libc.h>

int libc_function(int a)
{
    return libb_function(a) * libb_function(a);
}
#包括
#包括
int libc_函数(int a)
{
返回libb_函数(a)*libb_函数(a);
}

不要为每个库和应用程序创建单独的
项目
,而是创建一个“根”项目,子目录中的所有CMake文件都是该项目的一部分。换句话说,将
project(test)
保留在顶级
CMakeLists.txt
文件中,并删除(或注释掉)所有其他
project
命令。请试试看会发生什么,我刚试过。我得到了同样的结果。它将与本机工具链一起工作,但在交叉编译时失败。嗯。。。仔细阅读错误消息,静态库和共享库之间似乎有一些混淆(CMake为共享库创建目标,但依赖项是静态库)。也许您应该明确说明要在命令中创建哪种类型的库?正如在
add_library(liba SHARED liba.c)
中一样,尝试的另一件事是将库重命名为普通的
a
b
c
?因为CMake将自动为您在POSIX系统上添加
lib
前缀。我猜测这是因为
liblibb.so
依赖于普通的
liba.a
,而不是
libliba.a
(或者正确的
libliba.so
)。事实上,CMake无法找到它生成的东西(
liba.so
),通常表明项目的代码做了一些错误的事情。我在你的代码中没有看到这些东西,所以可能是工具链写错了。如果不查看其代码,就很难获得更详细的信息。