将 Makefile 转换为 CMake 找不到链接的共享对象

Converting Makefile to CMake cannot find linked shared object

我正在尝试将工作 Makefile 转换为 CMake,需要一些帮助。我正在尝试从 Ubuntu20 机器交叉编译一个用于 yocto 设备的小程序,该机器试图使用 cmake link 到设备共享对象文件。我有一个构建工作程序的工作 Makefile。但是,当我尝试使用 CMakeList 文件执行此操作时,它在 make 阶段失败 linking 到共享对象 linker 标志。

代码的文件结构如下;

Parent
  - include/
      - file1.h
      - file2.h
      - xxx.h
  - lib/
      - libOBD2.so 
  - src/
      - test.c
  - CMakeLists.txt   # Not working
  - Makefile.        # working

正在从程序父目录中 link 编辑共享对象,但我也在 here/usr/lib/usr/local/lib 中尝试使用它,但是没有变化。

正在工作Makefile

.prevent_execution:
exit 0

#remove @ for no make command prints
DEBUG = @

APP_DIR = .
BUILD_DIR := $(APP_DIR)/build
SRC_DIRS := $(APP_DIR)/src
HEADER_DIR := $(APP_DIR)/include
APP_LIBRARY_DIR = $(APP_DIR)/lib
APP_NAME = test

# Locate all the source c and cpp files to be built
APP_SRC_FILES := $(shell find $(SRC_DIRS) -name '*.cpp' -or -name '*.c')

INC_DIRS := $(shell find $(HEADER_DIR) -type d)
# Add a prefix to INC_DIRS. So moduleA would become -ImoduleA. GCC understands this -I flag
INC_FLAGS := $(addprefix -I,$(INC_DIRS))

CFLAGS+=-fPIC

PATH1 = /opt/fsl-imx-x11/5.4-zeus/sysroots/x86_64-pokysdk-linux/usr/include/
PATH2 = /opt/fsl-imx-x11/5.4-zeus/sysroots/x86_64-pokysdk-linux/usr/include/libxml2/
PATH3 = /opt/fsl-imx-x11/5.4-zeus/sysroots/cortexa7t2hf-neon-poky-linux-gnueabi/usr/lib/

MAKE_CMD = -g -O0 -s -o $(BUILD_DIR)/$(APP_NAME) $(INC_FLAGS) $(APP_SRC_FILES) -    I$(PATH1) -I$(PATH2) -L$(APP_LIBRARY_DIR) -lz -lOBD2 -lssl -lcrypto -lcurl -lxml2 -L$(PATH3) -lm -ldl -lpthread -lrt

all:
    $(DEBUG) $(CC) $(CFLAGS) $(MAKE_CMD)

clean:
    rm -f $(BUILD_DIR)/$(APP_NAME)

CmakeLists.txt

cmake_minimum_required( VERSION 3.5 )
set(CMAKE_SYSTEM_NAME Linux)
set(CMAKE_SYSTEM_PROCESSOR ARM)

# -fPIC
set(CMAKE_POSITION_INDEPENDENT_CODE ON)

project(iwtest)

set(PATH1 "/opt/fsl-imx-x11/5.4-zeus/sysroots/x86_64-pokysdk-linux/usr/include/")
set(PATH2 "/opt/fsl-imx-x11/5.4-zeus/sysroots/x86_64-pokysdk-linux/usr/include/libxml2/")
set(PATH3 "/opt/fsl-imx-x11/5.4-zeus/sysroots/cortexa7t2hf-neon-poky-linux-gnueabi/usr/lib")

set(LIB_DIR "${CMAKE_SOURCE_DIR}/lib")

include_directories(${PROJECT_NAME} PRIVATE ${PATH1})
include_directories(${PROJECT_NAME} PRIVATE ${PATH2})
include_directories(${PROJECT_NAME} PRIVATE "${PROJECT_SOURCE_DIR}/include")

set(SOURCE_FILES src/test.c)

add_definitions("-g")
add_definitions("-O0")
add_definitions("-s")

# Connect the libOBD2 library to the project
add_library(libOBD2 SHARED IMPORTED)
set_target_properties(libOBD2 PROPERTIES IMPORTED_LOCATION ${LIB_DIR}/libOBD2.so)
include_directories(libOBD2 INTERFACE ${CMAKE_SOURCE_DIR}/lib)

add_executable(${PROJECT_NAME} ${SOURCE_FILES})

# target_link_libraries(${PROJECT_NAME} PRIVATE ${PATH3})
target_link_libraries(${PROJECT_NAME} PUBLIC libOBD2)

target_link_options(${PROJECT_NAME} PRIVATE -lz -lOBD2 -lssl -lcrypto -lcurl -lxml2 -L$(PATH3) -lm -ldl -lpthread -lrt)
# target_link_options(${PROJECT_NAME} PRIVATE -I$(PATH1) -I$(PATH2) -L$(LIB_DIR) -lz -lOBD2 -lssl -lcrypto -lcurl -lxml2 -L$(PATH3) -lm -ldl -lpthread -lrt)

cmake

的输出
-- Toolchain file defaulted to '/opt/fsl-imx-x11/5.4-zeus/sysroots/x86_64-pokysdk-linux/usr/share/cmake/OEToolchainConfig.cmake'
-- The C compiler identification is GNU 9.2.0
-- The CXX compiler identification is GNU 9.2.0
-- Detecting C compiler ABI info
-- Detecting C compiler ABI info - done
-- Check for working C compiler: /opt/fsl-imx-x11/5.4-zeus/sysroots/x86_64-pokysdk-linux/usr/bin/arm-poky-linux-gnueabi/arm-poky-linux-gnueabi-gcc - skipped
-- Detecting C compile features
-- Detecting C compile features - done
-- Detecting CXX compiler ABI info
-- Detecting CXX compiler ABI info - done
-- Check for working CXX compiler: /opt/fsl-imx-x11/5.4-zeus/sysroots/x86_64-pokysdk-linux/usr/bin/arm-poky-linux-gnueabi/arm-poky-linux-gnueabi-g++ - skipped
-- Detecting CXX compile features
-- Detecting CXX compile features - done
-- Configuring done
-- Generating done
-- Build files have been written to: /home/dev/Workspace/build/cmakebuild

make VERBOSE=1

的输出
/opt/fsl-imx-x11/5.4-zeus/sysroots/x86_64-pokysdk-linux/usr/bin/cmake -S/home/dev/Development/iwave-test-code -B/home/dev/Workspace/build/cmakebuild --check-build-system CMakeFiles/Makefile.cmake 0
/opt/fsl-imx-x11/5.4-zeus/sysroots/x86_64-pokysdk-linux/usr/bin/cmake -E cmake_progress_start /home/dev/Workspace/build/cmakebuild/CMakeFiles /home/dev/Workspace/build/cmakebuild//CMakeFiles/progress.marks
make  -f CMakeFiles/Makefile2 all
make[1]: Entering directory '/home/dev/Workspace/build/cmakebuild'
make  -f CMakeFiles/iwtest.dir/build.make CMakeFiles/iwtest.dir/depend
make[2]: Entering directory '/home/dev/Workspace/build/cmakebuild'
cd /home/dev/Workspace/build/cmakebuild && /opt/fsl-imx-x11/5.4-zeus/sysroots/x86_64-pokysdk-linux/usr/bin/cmake -E cmake_depends "Unix Makefiles" /home/dev/Development/iwave-test-code /home/dev/Development/iwave-test-code /home/dev/Workspace/build/cmakebuild /home/dev/Workspace/build/cmakebuild /home/dev/Workspace/build/cmakebuild/CMakeFiles/iwtest.dir/DependInfo.cmake --color=
make[2]: Leaving directory '/home/dev/Workspace/build/cmakebuild'
make  -f CMakeFiles/iwtest.dir/build.make CMakeFiles/iwtest.dir/build
make[2]: Entering directory '/home/dev/Workspace/build/cmakebuild'
[ 50%] Building C object CMakeFiles/iwtest.dir/src/test.c.o
/opt/fsl-imx-x11/5.4-zeus/sysroots/x86_64-pokysdk-linux/usr/bin/arm-poky-linux-gnueabi/arm-poky-linux-gnueabi-gcc   -mthumb -mfpu=neon -mfloat-abi=hard -mcpu=cortex-a7 -fstack-protector-strong  -D_FORTIFY_SOURCE=2 -Wformat -Wformat-security -Werror=format-security --sysroot=/opt/fsl-imx-x11/5.4-zeus/sysroots/cortexa7t2hf-neon-poky-linux-gnueabi --sysroot=/opt/fsl-imx-x11/5.4-zeus/sysroots/cortexa7t2hf-neon-poky-linux-gnueabi  -I/home/dev/Development/iwave-test-code/iwtest -I/home/dev/Development/iwave-test-code/PRIVATE -I/opt/fsl-imx-x11/5.4-zeus/sysroots/x86_64-pokysdk-linux/usr/include -I/opt/fsl-imx-x11/5.4-zeus/sysroots/x86_64-pokysdk-linux/usr/include/libxml2 -I/home/dev/Development/iwave-test-code/include -I/home/dev/Development/iwave-test-code/libOBD2 -I/home/dev/Development/iwave-test-code/INTERFACE -I/home/dev/Development/iwave-test-code/lib -O2 -pipe -g -feliminate-unused-debug-types  -fPIE   -g -O0 -s -o CMakeFiles/iwtest.dir/src/test.c.o -c /home/dev/Development/iwave-test-code/src/test.c
In file included from /opt/fsl-imx-x11/5.4-zeus/sysroots/cortexa7t2hf-neon-poky-linux-gnueabi/usr/include/bits/libc-header-start.h:33,
                 from /opt/fsl-imx-x11/5.4-zeus/sysroots/cortexa7t2hf-neon-poky-linux-gnueabi/usr/include/stdio.h:27,
                 from /home/dev/Development/iwave-test-code/src/test.c:1:
/opt/fsl-imx-x11/5.4-zeus/sysroots/cortexa7t2hf-neon-poky-linux-gnueabi/usr/include/features.h:382:4: warning: #warning _FORTIFY_SOURCE requires compiling with optimization (-O) [-Wcpp]
  382 | #  warning _FORTIFY_SOURCE requires compiling with optimization (-O)
      |    ^~~~~~~
[100%] Linking C executable iwtest
/opt/fsl-imx-x11/5.4-zeus/sysroots/x86_64-pokysdk-linux/usr/bin/cmake -E cmake_link_script CMakeFiles/iwtest.dir/link.txt --verbose=1
/opt/fsl-imx-x11/5.4-zeus/sysroots/x86_64-pokysdk-linux/usr/bin/arm-poky-linux-gnueabi/arm-poky-linux-gnueabi-gcc   -mthumb -mfpu=neon -mfloat-abi=hard -mcpu=cortex-a7 -fstack-protector-strong  -D_FORTIFY_SOURCE=2 -Wformat -Wformat-security -Werror=format-security --sysroot=/opt/fsl-imx-x11/5.4-zeus/sysroots/cortexa7t2hf-neon-poky-linux-gnueabi --sysroot=/opt/fsl-imx-x11/5.4-zeus/sysroots/cortexa7t2hf-neon-poky-linux-gnueabi  -O2 -pipe -g -feliminate-unused-debug-types  -Wl,-O1 -Wl,--hash-style=gnu -Wl,--as-needed -fstack-protector-strong -Wl,-z,relro,-z,now -lz -lOBD2 -lssl -lcrypto -lcurl -lxml2 "-L$$(PATH3)" -lm -ldl -lpthread -lrt CMakeFiles/iwtest.dir/src/test.c.o -o iwtest  -Wl,-rpath,/home/dev/Development/iwave-test-code/lib /home/dev/Development/iwave-test-code/lib/libOBD2.so 
/opt/fsl-imx-x11/5.4-zeus/sysroots/x86_64-pokysdk-linux/usr/libexec/arm-poky-linux-gnueabi/gcc/arm-poky-linux-gnueabi/9.2.0/real-ld: cannot find -lOBD2
collect2: error: ld returned 1 exit status
make[2]: *** [CMakeFiles/iwtest.dir/build.make:104: iwtest] Error 1
make[2]: Leaving directory '/home/dev/Workspace/build/cmakebuild'
make[1]: *** [CMakeFiles/Makefile2:95: CMakeFiles/iwtest.dir/all] Error 2
make[1]: Leaving directory '/home/dev/Workspace/build/cmakebuild'
make: *** [Makefile:103: all] Error 2

非常感谢任何帮助。提前致谢。

感谢 comment the solution was to remove the -lOBD2 from the target_link_options. As per 建议,现在所有链接器选项都通过 target_link_libraries 链接。

解决CMakeLists.txt

# remove the target_link_options line
# target_link_options(${PROJECT_NAME} PRIVATE -lz -lOBD2 -lssl -lcrypto -lcurl -lxml2 -L$(PATH3) -lm -ldl -lpthread -lrt) 

# replace with
target_link_libraries(${PROJECT_NAME} PUBLIC libOBD2 pthread ssl crypto curl xml2 m dl rt)

附带说明一下,当我为 yocto 设备进行交叉编译时,libOBD2.so 位于与 ${CMAKE_SOURCE_DIR}/lib 的交叉编译 pc 不同的目录中。为了解决这个问题,我将 libOBD2.so 复制到设备上看到的同一目录,在本例中是 /usr/lib 并将 LIB_DIR 更改为 set(LIB_DIR "/usr/lib").

有一种更简单的方法可以做到这一切。我碰巧使用相同的工具链,并且可能与您使用的是完全相同的 iWave 远程信息处理设备。我的 CMakeLists.txt 文件是通用的,里面什么都没有 toolchain-specific(platform-specific 库除外)...

cmake_minimum_required(VERSION 3.0.0)
project(testapp VERSION 0.1.0)

add_executable(testapp src/testapp.cpp)

target_include_directories(testapp PUBLIC include)

set(THREADS_PREFER_PTHREAD_FLAG ON)
find_package(Threads REQUIRED)
target_link_directories(testapp PUBLIC lib)
target_link_libraries(testapp PRIVATE Threads::Threads libOBD2.so)

一旦我的项目文件夹中有了这个文件,我就会从终端运行执行以下命令:

source /opt/fsl-imx-x11/5.4-zeus/environment-setup-cortexa7t2hf-neon-poky-linux-gnueabi
mkdir build
cd build
cmake ..
make

CMake 现在会自动检测工具链,并生成适当的 makefile 来实际构建您的项目。好处是,如果您没有链接 platform-specific 库(例如 iWave 提供的 libOBD2.so 文件),您可以轻松地将构建重新定位到另一个环境——我已经成功切换到Raspberry Pi,或原生 Ubuntu。这完全取决于 CMake 在您 运行 时检测到的工具链。 “source”命令设置它,CMake 从那里获取所有内容...

此致, 大卫