Issue
I am attempting to convert a working Makefile into a CMake and need a little assistance. I am trying to cross compile a small program for a yocto device from a Ubuntu20 machine that is trying to link to the devices shared object file with cmake. I have a working Makefile that builds a working program. However, when I try and do this with a CMakeList file it fails at the make stage linking to the shared objects linker flag.
The file structure of the code is as follows;
Parent
- include/
- file1.h
- file2.h
- xxx.h
- lib/
- libOBD2.so
- src/
- test.c
- CMakeLists.txt # Not working
- Makefile. # working
The shared object is being linked from within the program parent directory but I have also tried with it in the /usr/lib
and /usr/local/lib
from here but with no change.
The working 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)
The 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)
The output of 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
The output of 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
Any help is much appreciated. Thanks in advance.
Solution
Thanks to Tsyvarev comment the solution was to remove the -lOBD2
from the target_link_options
. As per Tsyvarev suggestion now all the linker options are linked through target_link_libraries
.
The solution to the 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)
On a side note, as i was cross-compiling for a yocto device the libOBD2.so
was located in a different directory to the cross-compile pc of ${CMAKE_SOURCE_DIR}/lib
. To fix this I copied libOBD2.so
to the same directory seen on the device, in this case it was /usr/lib
and change LIB_DIR
to set(LIB_DIR "/usr/lib")
.
Answered By - heych Answer Checked By - Robin (WPSolving Admin)