I created a cross compiler for the jetson nano using the following bash script:
#!/bin/bash
set -e
# mkdir cross-scratchpad
# cd cross-scratchpad
# FILES="http://ftpmirror.gnu.org/binutils/binutils-2.36.tar.gz
# http://ftpmirror.gnu.org/gcc/gcc-11.1.0/gcc-11.1.0.tar.gz &
# http://ftpmirror.gnu.org/glibc/glibc-2.33.tar.xz &
# http://ftpmirror.gnu.org/mpfr/mpfr-4.1.0.tar.xz
# http://ftpmirror.gnu.org/gmp/gmp-6.2.1.tar.xz &
# http://ftpmirror.gnu.org/mpc/mpc-1.2.1.tar.gz &
# ftp://gcc.gnu.org/pub/gcc/infrastructure/isl-0.18.0.tar.bz2
# ftp://gcc.gnu.org/pub/gcc/infrastructure/cloog-0.18.1.tar.gz
# https://developer.nvidia.com/embedded/l4t/r32_release_v5.2/sources/t210/public_sources.tbz2"
# echo "$FILES" | xargs -n 1 -P 5 wget
# wait
for f in *.tar*; do tar xf "$f"; done
cd gcc-11.1.0
ln -s ../mpfr-4.1.0 mpfr
ln -s ../gmp-6.2.1 gmp
ln -s ../mpc-1.2.1 mpc
ln -s ../isl-0.18 isl
ln -s ../cloog-0.18.1 cloog
cd ..
sudo rm -rf /opt/cross/*
export PATH=/opt/cross/bin:"$PATH"
mkdir build-binutils
cd build-binutils
../binutils-2.36/configure --prefix=/opt/cross --target=aarch64-linux --disable-multilib --disable-werror
make -j8
make install
cd ..
tar -xjf public_sources.tbz2
cd Linux_for_Tegra/source/public/
tar -xjf kernel_src.tbz2
cd kernel/kernel-4.9
make ARCH=arm64 INSTALL_HDR_PATH=/opt/cross/aarch64-linux headers_install
cd ../../../../..
mkdir -p build-gcc
cd build-gcc
../gcc-11.1.0/configure --prefix=/opt/cross --target=aarch64-linux --enable-languages=c,c++ --disable-multilib --disable-werror
make -j8 all-gcc
make install-gcc
cd ..
mkdir -p build-glibc
cd build-glibc
../glibc-2.33/configure --prefix=/opt/cross/aarch64-linux --build="$MACHTYPE" --host=aarch64-linux --target=aarch64-linux --with-headers=/opt/cross/aarch64-linux/include --disable-multilib --disable-werror libc_cv_forced_unwind=yes
make install-bootstrap-headers=yes install-headers
make -j8 csu/subdir_lib
install csu/crt1.o csu/crti.o csu/crtn.o /opt/cross/aarch64-linux/lib
aarch64-linux-gcc -nostdlib -nostartfiles -shared -x c /dev/null -o /opt/cross/aarch64-linux/lib/libc.so
touch /opt/cross/aarch64-linux/include/gnu/stubs.h
cd ..
cd build-gcc
make -j8 all-target-libgcc
make install-target-libgcc
cd ..
cd build-glibc
make -j8
make install
cd ..
cd build-gcc
make -j8
make install
cd ..
I am now trying to use it with cmake to build a project.
I have written the following toolchain file to use when creating the makefile with CMake:
set(CMAKE_SYSTEM_NAME Linux)
set(CMAKE_SYSTEM_PROCESSOR arm)
set(CMAKE_FIND_ROOT_PATH path/to/root/of/jetson/nano)
set(CROSS_ROOT /opt/cross/bin)
set(CMAKE_AR ${CROSS_ROOT}/aarch64-linux-ar)
set(CMAKE_ASM_COMPILER ${CROSS_ROOT}/aarch64-linux-as)
set(CMAKE_C_COMPILER ${CROSS_ROOT}/aarch64-linux-gcc)
set(CMAKE_CXX_COMPILER ${CROSS_ROOT}/aarch64-linux-g++)
set(CMAKE_LINKER ${CROSS_ROOT}/aarch64-linux-ld)
set(CMAKE_OBJCOPY ${CROSS_ROOT}/aarch64-linux-objcopy)
set(CMAKE_RANLIB ${CROSS_ROOT}/aarch64-linux-ranlib)
set(CMAKE_SIZE ${CROSS_ROOT}/aarch64-linux-size)
set(CMAKE_STRIP ${CROSS_ROOT}/aarch64-linux-strip)
set(CMAKE_GCOV ${CROSS_ROOT}/aarch64-linux-gcov)
set(CMAKE_C_FLAGS "${APP_C_FLAGS} -Wno-psabi" CACHE INTERNAL "")
set(CMAKE_CXX_FLAGS "${APP_CXX_FLAGS} ${CMAKE_C_FLAGS}" CACHE INTERNAL "")
set(CMAKE_C_FLAGS_DEBUG "-O0 -g" CACHE INTERNAL "")
set(CMAKE_C_FLAGS_RELEASE "-O3 -DNDEBUG" CACHE INTERNAL "")
set(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_C_FLAGS_DEBUG}" CACHE INTERNAL "")
set(CMAKE_CXX_FLAGS_RELEASE "${CMAKE_C_FLAGS_RELEASE}" CACHE INTERNAL "")
set(CMAKE_FIND_ROOT_PATH_MODE_PROGRAM NEVER)
set(CMAKE_FIND_ROOT_PATH_MODE_LIBRARY ONLY)
set(CMAKE_FIND_ROOT_PATH_MODE_INCLUDE ONLY)
The path/to/root/of/jetson/nano is a path to a root directory I created using rsync. The project compiles fine when I run cmake .. && make -j8 on the target machine.
Configuring on the host machine using cmake .. -DCMAKE_TOOLCHAIN_FILE=../toolchain.cmake succeeds with:
-- The C compiler identification is GNU 11.1.0
-- The CXX compiler identification is GNU 11.1.0
-- Detecting C compiler ABI info
-- Detecting C compiler ABI info - done
-- Check for working C compiler: /opt/cross/bin/aarch64-linux-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/cross/bin/aarch64-linux-g++ - skipped
-- Detecting CXX compile features
-- Detecting CXX compile features - done
-- Found OpenCV: /usr (found version "4.5.3")
-- Configuring done
-- Generating done
-- Build files have been written to: /path/to/my/project/build
However, when I run make -j8 I get an error on every include in the form:
fatal error: glm/gtc/matrix_transform.hpp: No such file or directory
4 | #include <glm/gtc/matrix_transform.hpp>
What's going on and how do I fix this?
Related
I am new to Docker container and kubenetes cluster. I am trying to run following section of command using buildah
##install cmake
USER root
RUN apt-get update && apt-get -y install cmake
USER ${user}
WORKDIR $HOME
## bustools_dev
RUN git clone https://github.com/Yenaled/bustools.git && \
cd bustools && \
mkdir build && \
cd build
RUN cmake ../
RUN make
RUN cd src
RUN mv bustools bustools_dev
RUN ENV PATH=$HOME/bustools/build/src/:${PATH}
but get the following error. What am I missing here?
STEP 17: WORKDIR $HOME
WARN[0002] SHELL is not supported for OCI image format, [/bin/bash -o pipefail -c] will be ignored. Must use `docker` format
--> 770a1b90326
STEP 18: RUN git clone https://github.com/Yenaled/bustools.git && cd bustools && mkdir build && cd build
Cloning into 'bustools'...
WARN[0005] SHELL is not supported for OCI image format, [/bin/bash -o pipefail -c] will be ignored. Must use `docker` format
--> 2b87555e927
STEP 19: RUN cmake ../
CMake Error: The source directory "/home" does not appear to contain CMakeLists.txt.
Specify --help for usage, or press the help button on the CMake GUI.
error building at STEP "RUN cmake ../": error while running runtime: exit status 1
ERRO[0111] exit status 1
I'd simplify the Dockerfile to avoid the issues with the WORKDIR setup that I think are the cause of the problem:
FROM debian:11
RUN apt-get update \
&& apt-get install --assume-yes --no-install-recommends --quiet \
ca-certificates \
cmake \
git \
g++ \
make \
libzip-dev \
&& apt-get clean all
WORKDIR /usr/local/src
RUN git clone https://github.com/Yenaled/bustools.git
RUN mkdir -p /usr/local/src/bustools/build
RUN cd /usr/local/src/bustools/build \
&& cmake .. \
&& make
[...]
Output
[...]
STEP 3/6: WORKDIR /usr/local/src
--> ffb056fd5b3
STEP 4/6: RUN git clone https://github.com/Yenaled/bustools.git
Cloning into 'bustools'...
--> 83afa44c5c8
STEP 5/6: RUN mkdir -p /usr/local/src/bustools/build
--> 2e6ed328088
STEP 6/6: RUN cd /usr/local/src/bustools/build && cmake .. && make
-- The C compiler identification is GNU 10.2.1
-- The CXX compiler identification is GNU 10.2.1
-- Detecting C compiler ABI info
-- Detecting C compiler ABI info - done
-- Check for working C compiler: /usr/bin/cc - 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: /usr/bin/c++ - skipped
-- Detecting CXX compile features
-- Detecting CXX compile features - done
release mode
-- Looking for pthread.h
-- Looking for pthread.h - found
-- Performing Test CMAKE_HAVE_LIBC_PTHREAD
-- Performing Test CMAKE_HAVE_LIBC_PTHREAD - Failed
-- Looking for pthread_create in pthreads
-- Looking for pthread_create in pthreads - not found
-- Looking for pthread_create in pthread
-- Looking for pthread_create in pthread - found
-- Found Threads: TRUE
-- Found ZLIB: /usr/lib/x86_64-linux-gnu/libz.so (found version "1.2.11")
-- Configuring done
-- Generating done
-- Build files have been written to: /usr/local/src/bustools/build
Scanning dependencies of target bustools_core
[ 4%] Building CXX object src/CMakeFiles/bustools_core.dir/BUSData.cpp.o
[ 8%] Building CXX object src/CMakeFiles/bustools_core.dir/Common.cpp.o
[ 13%] Building CXX object src/CMakeFiles/bustools_core.dir/bustools_capture.cpp.o
[ 17%] Building CXX object src/CMakeFiles/bustools_core.dir/bustools_clusterhist.cpp.o
[ 21%] Building CXX object src/CMakeFiles/bustools_core.dir/bustools_collapse.cpp.o
[ 26%] Building CXX object src/CMakeFiles/bustools_core.dir/bustools_correct.cpp.o
[ 30%] Building CXX object src/CMakeFiles/bustools_core.dir/bustools_count.cpp.o
[ 34%] Building CXX object src/CMakeFiles/bustools_core.dir/bustools_extract.cpp.o
[ 39%] Building CXX object src/CMakeFiles/bustools_core.dir/bustools_inspect.cpp.o
[ 43%] Building CXX object src/CMakeFiles/bustools_core.dir/bustools_linker.cpp.o
[ 47%] Building CXX object src/CMakeFiles/bustools_core.dir/bustools_main.cpp.o
[ 52%] Building CXX object src/CMakeFiles/bustools_core.dir/bustools_mash.cpp.o
[ 56%] Building CXX object src/CMakeFiles/bustools_core.dir/bustools_merge.cpp.o
[ 60%] Building CXX object src/CMakeFiles/bustools_core.dir/bustools_predict.cpp.o
[ 65%] Building CXX object src/CMakeFiles/bustools_core.dir/bustools_project.cpp.o
[ 69%] Building CXX object src/CMakeFiles/bustools_core.dir/bustools_sort.cpp.o
[ 73%] Building CXX object src/CMakeFiles/bustools_core.dir/bustools_text.cpp.o
[ 78%] Building CXX object src/CMakeFiles/bustools_core.dir/bustools_umicorrect.cpp.o
[ 82%] Building CXX object src/CMakeFiles/bustools_core.dir/bustools_whitelist.cpp.o
[ 86%] Building C object src/CMakeFiles/bustools_core.dir/roaring.c.o
[ 91%] Linking CXX static library libbustools_core.a
[ 91%] Built target bustools_core
Scanning dependencies of target bustools
[ 95%] Building CXX object src/CMakeFiles/bustools.dir/bustools_main.cpp.o
[100%] Linking CXX executable bustools
[100%] Built target bustools
--> b08bc457b5f
I run some command before the actual build
add_custom_target("${PROJECT_BUILD_NUM_FILE}"
COMMAND ${PROJECT_BUILD_NUM_UPDATE} "-p" "-x" -f ${PROJECT_SOURCE_DIR}/${MAIN_PATH}/${BOARD_NAME}/${PROJECT_BUILD_NUM_FILE}
)
add_dependencies(${EXECUTABLE_NAME} "${PROJECT_BUILD_NUM_FILE}" )
When I build first time (the project was build before)
>------ Build started: Project: CMakeLists, Configuration: Debug ------
[1/1] cmd.exe /C "cd /D C:\Users\Piotr\git\gPIMS-EG\out\build\IoT-Debug && C:\Users\Piotr\git\gPIMS-EG\stm-libs\pc-exe\buildnum.exe -p -x -f C:/Users/Piotr/git/gPIMS-EG/src/EG/BuildID.h"
Build number file used:C:/Users/Piotr/git/gPIMS-EG/src/EG/BuildID.h
Build file updated: Build Number: 22 DateCode: 0x1d6d
Build succeeded.
BuildID.h file was modified and saved. Modification date is set correctly.
On the second build it behaves correctly
>------ Build started: Project: CMakeLists, Configuration: Debug ------
[1/4] cmd.exe /C "cd /D C:\Users\Piotr\git\gPIMS-EG\out\build\IoT-Debug && C:\Users\Piotr\git\gPIMS-EG\stm-libs\pc-exe\buildnum.exe -p -x -f C:/Users/Piotr/git/gPIMS-EG/src/EG/BuildID.h"
Build number file used:C:/Users/Piotr/git/gPIMS-EG/src/EG/BuildID.h
Build file updated: Build Number: 23 DateCode: 0x1d6d
[2/4] C:\PROGRA~2\Atollic\TRUEST~1.0\ARMTools\bin\AR097D~1.EXE -DALLOW_SOFTWARE_BKPTS=1 -DARM_MATH_CM4 -DBOOTLOADER_VERSION=1 -DCOMPILE_FOR_EG=1 -DDEBUGFILEWRITE=1 -DDEBUG_RUN_WITHOUT_CHECKS=1 -DFORCE_CUBE_USB -DHSE_VALUE=8000000UL -DSLOWSPIDEBUG=0 -DSTM32L -DSTM32L476xx -DSTM32L4xx -DUSE_EMBEDDED_PHY=1 -DUSE_FULL_ASSERT -DUSE_FULL_LL_DRIVER="" -DUSE_HAL_DRIVER -DUSE_SWOTRACE=1 -DUSE_USB_OTG_FS=1 -DUSE_USB_OTG_HS=1 -D_DEBUG=1 -D_GNU_SOURCE=1 -D__USE_SIMPLE_SWO=0 -I../../../src -I../../../src/EG -I../../../src/ZM -I../../../src/inc -I../../../stm-libs/inc -I../../../stm-libs/Drivers -I../../../stm-libs/Services -I../../../stm-libs/Services/Utils -I../../../stm-libs/RTOS/Source/include -I../../../stm-libs/RTOS/Source/portable/GCC/ARM_CM4F -I../../../stm-libs/Libraries/CMSIS/Include -I../../../stm-libs/Libraries/CMSIS/Device/ST/STM32L4xx/Include -I../../../stm-libs/Libraries/CryptoLib/Inc -I../../../stm-libs/Libraries/CryptoLib/Inc/RNG -I../../../stm-libs/drivers/USBD -I../../../stm-libs/Libraries/Middlewares/ST/STM32_USB_Device_Library/Core/Inc -I../../../stm-libs/Libraries/USB/Device/Class/CDC/Inc -I../../../stm-libs/Libraries/USB/Device/Class/MSC_HID/Inc -I../../../stm-libs/Libraries/USB/Device/Core/Inc -I../../../stm-libs/Libraries/lwip/ports/STM32F4x7 -I../../../stm-libs/Libraries/lwip/ports/STM32F4x7/arch -I../../../stm-libs/Libraries/lwip/src -I../../../stm-libs/Libraries/lwip/src/include -I../../../stm-libs/drivers/USBH -I../../../stm-libs/Libraries/USB/Host/Class/AUDIO/Inc -I../../../stm-libs/Libraries/USB/Host/Class/CDC/Inc -I../../../stm-libs/Libraries/USB/Host/Class/HID/Inc -I../../../stm-libs/Libraries/USB/Host/Class/MSC/Inc -I../../../stm-libs/Libraries/USB/Host/Class/MTP/Inc -I../../../stm-libs/Libraries/USB/Host/Core/Inc -I../../../stm-libs/Libraries/USB/Host/Class/Template/Inc -I../../../stm-libs/Libraries/lwip/ports/STM32F4x7/FreeRTOS -I../../../stm-libs/Libraries/misc -I../../../stm-libs/Libraries/FatFs/src -I../../../stm-libs/Libraries/littleFS -I../../../stm-libs/Apps -I../../../stm-libsApps/SeqZM -I../../../stm-libs/Libraries/libc_e -I../../../stm-libs/Libraries -I../../../stm-hal-l4/Inc/Legacy -I../../../stm-hal-l4/Inc -I../../../stm-libs/Apps/Other -mthumb -mcpu=cortex-m4 -mfloat-abi=hard -mfpu=fpv4-sp-d16 -Og -g3 -T"C:/Users/Piotr/git/gPIMS-EG/src/EG/startup/EG.ld" -L"C:/Users/Piotr/git/gPIMS-EG/stm-libs/Libraries/CryptoLib" -lSTM32CryptographicV3.0.0_CM4_GCC_FPU -specs=nosys.specs -specs=nano.specs -Wl,-Map="EG.map" -static -Wl,-u,Reset_Handler -Wl,--gc-sections -Wl,--defsym=malloc_getpagesize_P=0x80 -Wl,--start-group -lc -lm -Wl,--end-group -ffunction-sections -fdata-sections -g -MD -MT CMakeFiles/GCEG-FW.dir/stm-libs/Apps/common/SC_Ver.c.obj -MF CMakeFiles\GCEG-FW.dir\stm-libs\Apps\common\SC_Ver.c.obj.d -o CMakeFiles/GCEG-FW.dir/stm-libs/Apps/common/SC_Ver.c.obj -c ../../../stm-libs/Apps/common/SC_Ver.c
In file included from ../../../stm-libs/Apps/common/SC_Ver.c:9:0:
C:\Users\Piotr\git\gPIMS-EG\stm-libs\Drivers\CAN-COB.h(267,2): warning GF07C7A44: #warning added to compile BP to change [-Wcpp]
#warning added to compile BP to change
^~~~~~~
[3/4] C:\PROGRA~2\Atollic\TRUEST~1.0\ARMTools\bin\AR097D~1.EXE -DALLOW_SOFTWARE_BKPTS=1 -DARM_MATH_CM4 -DBOOTLOADER_VERSION=1 -DCOMPILE_FOR_EG=1 -DDEBUGFILEWRITE=1 -DDEBUG_RUN_WITHOUT_CHECKS=1 -DFORCE_CUBE_USB -DHSE_VALUE=8000000UL -DSLOWSPIDEBUG=0 -DSTM32L -DSTM32L476xx -DSTM32L4xx -DUSE_EMBEDDED_PHY=1 -DUSE_FULL_ASSERT -DUSE_FULL_LL_DRIVER="" -DUSE_HAL_DRIVER -DUSE_SWOTRACE=1 -DUSE_USB_OTG_FS=1 -DUSE_USB_OTG_HS=1 -D_DEBUG=1 -D_GNU_SOURCE=1 -D__USE_SIMPLE_SWO=0 -I../../../src -I../../../src/EG -I../../../src/ZM -I../../../src/inc -I../../../stm-libs/inc -I../../../stm-libs/Drivers -I../../../stm-libs/Services -I../../../stm-libs/Services/Utils -I../../../stm-libs/RTOS/Source/include -I../../../stm-libs/RTOS/Source/portable/GCC/ARM_CM4F -I../../../stm-libs/Libraries/CMSIS/Include -I../../../stm-libs/Libraries/CMSIS/Device/ST/STM32L4xx/Include -I../../../stm-libs/Libraries/CryptoLib/Inc -I../../../stm-libs/Libraries/CryptoLib/Inc/RNG -I../../../stm-libs/drivers/USBD -I../../../stm-libs/Libraries/Middlewares/ST/STM32_USB_Device_Library/Core/Inc -I../../../stm-libs/Libraries/USB/Device/Class/CDC/Inc -I../../../stm-libs/Libraries/USB/Device/Class/MSC_HID/Inc -I../../../stm-libs/Libraries/USB/Device/Core/Inc -I../../../stm-libs/Libraries/lwip/ports/STM32F4x7 -I../../../stm-libs/Libraries/lwip/ports/STM32F4x7/arch -I../../../stm-libs/Libraries/lwip/src -I../../../stm-libs/Libraries/lwip/src/include -I../../../stm-libs/drivers/USBH -I../../../stm-libs/Libraries/USB/Host/Class/AUDIO/Inc -I../../../stm-libs/Libraries/USB/Host/Class/CDC/Inc -I../../../stm-libs/Libraries/USB/Host/Class/HID/Inc -I../../../stm-libs/Libraries/USB/Host/Class/MSC/Inc -I../../../stm-libs/Libraries/USB/Host/Class/MTP/Inc -I../../../stm-libs/Libraries/USB/Host/Core/Inc -I../../../stm-libs/Libraries/USB/Host/Class/Template/Inc -I../../../stm-libs/Libraries/lwip/ports/STM32F4x7/FreeRTOS -I../../../stm-libs/Libraries/misc -I../../../stm-libs/Libraries/FatFs/src -I../../../stm-libs/Libraries/littleFS -I../../../stm-libs/Apps -I../../../stm-libsApps/SeqZM -I../../../stm-libs/Libraries/libc_e -I../../../stm-libs/Libraries -I../../../stm-hal-l4/Inc/Legacy -I../../../stm-hal-l4/Inc -I../../../stm-libs/Apps/Other -mthumb -mcpu=cortex-m4 -mfloat-abi=hard -mfpu=fpv4-sp-d16 -Og -g3 -T"C:/Users/Piotr/git/gPIMS-EG/src/EG/startup/EG.ld" -L"C:/Users/Piotr/git/gPIMS-EG/stm-libs/Libraries/CryptoLib" -lSTM32CryptographicV3.0.0_CM4_GCC_FPU -specs=nosys.specs -specs=nano.specs -Wl,-Map="EG.map" -static -Wl,-u,Reset_Handler -Wl,--gc-sections -Wl,--defsym=malloc_getpagesize_P=0x80 -Wl,--start-group -lc -lm -Wl,--end-group -ffunction-sections -fdata-sections -g -MD -MT CMakeFiles/GCEG-FW.dir/stm-libs/Apps/WaveMC3/waveMC3SeqGUI.c.obj -MF CMakeFiles\GCEG-FW.dir\stm-libs\Apps\WaveMC3\waveMC3SeqGUI.c.obj.d -o CMakeFiles/GCEG-FW.dir/stm-libs/Apps/WaveMC3/waveMC3SeqGUI.c.obj -c ../../../stm-libs/Apps/WaveMC3/waveMC3SeqGUI.c
In file included from ../../../stm-libs/Drivers/CAN-G3M.h:31:0,
from ../../../stm-libs/Drivers/ioCmd.h:12,
from ../../../stm-libs/Services/srvCmd.h:9,
from ../../../src/EG/../ZM/zmServices.h:10,
from ../../../src/EG/ourServices.h:12,
from ../../../stm-libs/Apps/WaveMC3/waveMC3SeqGUI.c:5:
C:\Users\Piotr\git\gPIMS-EG\stm-libs\Drivers\CAN-COB.h(267,2): warning GF07C7A44: #warning added to compile BP to change [-Wcpp]
#warning added to compile BP to change
^~~~~~~
[4/4] cmd.exe /C "cd . && C:\PROGRA~2\Atollic\TRUEST~1.0\ARMTools\bin\AR097D~1.EXE -mthumb -mcpu=cortex-m4 -mfloat-abi=hard -mfpu=fpv4-sp-d16 -Og -g3 -T"C:/Users/Piotr/git/gPIMS-EG/src/EG/startup/EG.ld" -L"C:/Users/Piotr/git/gPIMS-EG/stm-libs/Libraries/CryptoLib" -lSTM32CryptographicV3.0.0_CM4_GCC_FPU -specs=nosys.specs -specs=nano.specs -Wl,-Map="EG.map" -static -Wl,-u,Reset_Handler -Wl,--gc-sections -Wl,--defsym=malloc_getpagesize_P=0x80 -Wl,--start-group -lc -lm -Wl,--end-group -ffunction-sections -fdata-sections -g #CMakeFiles\GCEG-FW.rsp -o GCEG-FW.elf && cmd.exe /C "cd /D C:\Users\Piotr\git\gPIMS-EG\out\build\IoT-Debug && "C:\Program Files (x86)\Atollic\TrueSTUDIO for STM32 9.3.0\ARMTools\bin\arm-atollic-eabi-objcopy.exe" GCEG-FW.elf --output-target=binary GCEG-FW.bin -j .isr_vector -j .VERSION_INFO -j .text -j .rodata -j .ARM.extab -j .ARM -j .preinit_array -j .init_array -j .fini_array -j .data -j .RAM_VectorTable -j .RAM_DATAfunctions -j .RAM_functions -v && "C:\Program Files (x86)\Atollic\TrueSTUDIO for STM32 9.3.0\ARMTools\bin\arm-atollic-eabi-size.exe" GCEG-FW.elf --format=Berkeley""
copy from `GCEG-FW.elf' [elf32-littlearm] to `GCEG-FW.bin' [binary]
text data bss dec hex filename
210428 36680 54020 301128 49848 GCEG-FW.elf
Build succeeded.
It looks like ninja is checking dependencies before the actual build starts and ignores meanwhile file changed. Is there any way to force cmake/ninja to recheck dependecies after custom target is build (ie prgram that thenges the build is run).
It looks like ninja is checking dependencies before the actual build starts and ignores meanwhile file change
Hey! Yes. Because DEPFILEs from C source files are generated at the same time as they are compiled, cmake has no way to know beforehand which file depends on which. It would have to do two passes - first to get dependencies and then to compile (which would be a nice feature, but actually hard to implement). It happens in one pass during compilation (-MD -MT flags), so cmake has no way of knowing that one file depends on that header. I also advise:
Do not modify files in your source tree. Keep all changes in BINARY_DIR.
Do not modify files. Generate new files. It's easier and generally, less state = less problems.
Try it such:
# Inside binary_dir
set(PROJECT_BUILD_NUM_FILE ${CMAKE_CURRENT_BINARY_DIR}/gen/buildid_gen.h)
# Add #include <buildid_gen.h> to your buildid.h
add_custom_command(
OUTPUT ${PROJECT_BUILD_NUM_FILE}
COMMAND ${PROJECT_BUILD_NUM_UPDATE} "-p" "-x" -f ${PROJECT_BUILD_NUM_FILE}
DEPENDS ${PROJECT_BUILD_NUM_UPDATE}
)
add_custom_target(buildid_gen
COMMENT "Yooohooo!"
DEPENDS ${PROJECT_BUILD_NUM_FILE}
)
add_executable(${EXECUTABLE_NAME} ${PROJECT_BUILD_NUM_FILE} ${some_other_sources})
target_add_include_directories(${EXECTABLE_NAME} PUBLIC
# add include directory, so that buildid_gen is found
${CMAKE_CURRENT_BINARY_DIR}/gen
)
# this *helps*
add_dependencies(${EXECUTABLE_NAME} buildid_gen)
Is there any way to force cmake/ninja to recheck dependecies after custom target is build (ie prgram that thenges the build is run).
The real proper way ™ would be to manually track all files that depend on the file (you could think of grep -l '#include <buildid_gen.h> to get the list files) and communicate to cmake the dependency relation:
add_source_file_properties(${sources_that_include_buildid_gen} PROPERTIES OBJECT_DEPENDS ${PROJECT_BUILD_NUM_FILE})
Tracking dependencies is easier if you use a runtime interface (ie. long get_build_id();) cause then only one .c file that implements the interface will depend on the generated file.
There are also some projects that are compiled in two passes because of such dependencies, you have to first cmake .. --target buildid_gen and then cmake .. --target actually_compile each time you compile.
Also maybe execute_process is more appropriate if the file is setup once per build.
I am using CMake and MinGW-w64 64-bit to build. I have used this exact same setup with the same compiler on my other PC and it has worked. Not sure what's wrong.
I have the MinGW-w64 bin in my PATH. When I run cmake and do not specify the compiler path, it generates MinGW Makefiles successfully. However, when I specify the compiler (which I know does work, I got it from winlibs.com) it produces the following log. I am running Windows 10.
Detecting C compiler ABI info failed to compile with the following output:
Change Dir: C:/Libraries/Projects/CMakeTest/build/MinGW-10.1.0-64-bit/debug/CMakeFiles/CMakeTmp
Run Build Command(s):C:/MinGW/MinGW-10.1.0-64-bit/bin/mingw32-make.exe cmTC_a01cd/fast && C:/MinGW/MinGW-10.1.0-64-bit/bin/mingw32-make.exe -f CMakeFiles\cmTC_a01cd.dir\build.make CMakeFiles/cmTC_a01cd.dir/build
mingw32-make[1]: Entering directory 'C:/Libraries/Projects/CMakeTest/build/MinGW-10.1.0-64-bit/debug/CMakeFiles/CMakeTmp'
Building C object CMakeFiles/cmTC_a01cd.dir/CMakeCCompilerABI.c.obj
C:\MinGW\MinGW-10.1.0-64-bit\bin\x86_64-w64-mingw32-gcc.exe -v -o CMakeFiles\cmTC_a01cd.dir\CMakeCCompilerABI.c.obj -c "C:\Program Files\CMake\share\cmake-3.18\Modules\CMakeCCompilerABI.c"
Using built-in specs.
COLLECT_GCC=C:\MinGW\MinGW-10.1.0-64-bit\bin\x86_64-w64-mingw32-gcc.exe
Target: x86_64-w64-mingw32
Configured with: ../configure --prefix=/R/winlibs64_10.1.0/inst_gcc-10.1.0/share/gcc --build=x86_64-w64-mingw32 --host=x86_64-w64-mingw32 --with-pkgversion='MinGW-W64 x86_64-posix-seh, built by Brecht Sanders' --with-tune=generic --enable-checking=release --enable-threads=posix --disable-sjlj-exceptions --disable-libunwind-exceptions --enable-serial-configure --disable-bootstrap --enable-host-shared --enable-plugin --enable-default-ssp --disable-rpath --disable-libstdcxx-pch --enable-libstdcxx-time=yes --disable-libstdcxx-debug --disable-version-specific-runtime-libs --with-stabs --disable-symvers --enable-languages=c,c++,fortran,lto,objc,obj-c++,d --disable-gold --disable-nls --disable-stage1-checking --disable-win32-registry --disable-multilib --enable-ld --enable-libquadmath --enable-libada --enable-libssp --enable-libstdcxx --enable-lto --enable-fully-dynamic-string --enable-libgomp --enable-graphite --enable-mingw-wildcard --with-mpc=/d/winlibs64_10.1.0/custombuilt --with-mpfr=/d/winlibs64_10.1.0/custombuilt --with-gmp=/d/winlibs64_10.1.0/custombuilt --with-isl=/d/winlibs64_10.1.0/custombuilt --enable-install-libiberty --enable-__cxa_atexit --without-included-gettext --with-diagnostics-color=auto --with-libiconv --with-system-zlib --with-build-sysroot=/R/winlibs64_10.1.0/gcc-10.1.0/build_mingw/mingw-w64
Thread model: posix
Supported LTO compression algorithms: zlib zstd
gcc version 10.1.0 (MinGW-W64 x86_64-posix-seh, built by Brecht Sanders)
COLLECT_GCC_OPTIONS='-v' '-o' 'CMakeFiles\cmTC_a01cd.dir\CMakeCCompilerABI.c.obj' '-c' '-mtune=generic' '-march=x86-64'
c:/mingw/mingw-10.1.0-64-bit/bin/../libexec/gcc/x86_64-w64-mingw32/10.1.0/cc1.exe -quiet -v -iprefix c:\mingw\mingw-10.1.0-64-bit\bin\../lib/gcc/x86_64-w64-mingw32/10.1.0/ -D_REENTRANT C:\Program Files\CMake\share\cmake-3.18\Modules\CMakeCCompilerABI.c -quiet -dumpbase CMakeCCompilerABI.c -mtune=generic -march=x86-64 -auxbase-strip CMakeFiles\cmTC_a01cd.dir\CMakeCCompilerABI.c.obj -version -o C:\Users\gvcal\AppData\Local\Temp\ccHRxkpy.s
GNU C17 (MinGW-W64 x86_64-posix-seh, built by Brecht Sanders) version 10.1.0 (x86_64-w64-mingw32)
compiled by GNU C version 10.1.0, GMP version 6.2.0, MPFR version 4.0.2, MPC version 1.1.0, isl version isl-0.22.1-GMP
GGC heuristics: --param ggc-min-expand=100 --param ggc-min-heapsize=131072
ignoring duplicate directory "c:/mingw/mingw-10.1.0-64-bit/lib/gcc/../../lib/gcc/x86_64-w64-mingw32/10.1.0/include"
ignoring nonexistent directory "R:/winlibs64_10.1.0/inst_gcc-10.1.0/share/gcc/include"
ignoring nonexistent directory "/R/winlibs64_10.1.0/inst_gcc-10.1.0/share/gcc/include"
ignoring duplicate directory "c:/mingw/mingw-10.1.0-64-bit/lib/gcc/../../lib/gcc/x86_64-w64-mingw32/10.1.0/include-fixed"
ignoring duplicate directory "c:/mingw/mingw-10.1.0-64-bit/lib/gcc/../../lib/gcc/x86_64-w64-mingw32/10.1.0/../../../../x86_64-w64-mingw32/include"
ignoring nonexistent directory "/mingw/include"
#include "..." search starts here:
#include <...> search starts here:
c:\mingw\mingw-10.1.0-64-bit\bin\../lib/gcc/x86_64-w64-mingw32/10.1.0/include
c:\mingw\mingw-10.1.0-64-bit\bin\../lib/gcc/x86_64-w64-mingw32/10.1.0/../../../../include
c:\mingw\mingw-10.1.0-64-bit\bin\../lib/gcc/x86_64-w64-mingw32/10.1.0/include-fixed
c:\mingw\mingw-10.1.0-64-bit\bin\../lib/gcc/x86_64-w64-mingw32/10.1.0/../../../../x86_64-w64-mingw32/include
End of search list.
GNU C17 (MinGW-W64 x86_64-posix-seh, built by Brecht Sanders) version 10.1.0 (x86_64-w64-mingw32)
compiled by GNU C version 10.1.0, GMP version 6.2.0, MPFR version 4.0.2, MPC version 1.1.0, isl version isl-0.22.1-GMP
GGC heuristics: --param ggc-min-expand=100 --param ggc-min-heapsize=131072
Compiler executable checksum: 21a8d9a0add79f637093bff9641d5f35
COLLECT_GCC_OPTIONS='-v' '-o' 'CMakeFiles\cmTC_a01cd.dir\CMakeCCompilerABI.c.obj' '-c' '-mtune=generic' '-march=x86-64'
c:/mingw/mingw-10.1.0-64-bit/bin/../lib/gcc/x86_64-w64-mingw32/10.1.0/../../../../x86_64-w64-mingw32/bin/as.exe -v -o CMakeFiles\cmTC_a01cd.dir\CMakeCCompilerABI.c.obj C:\Users\gvcal\AppData\Local\Temp\ccHRxkpy.s
GNU assembler version 2.34 (x86_64-w64-mingw32) using BFD version (Binutils for MinGW-W64 x86_64, built by Brecht Sanders) 2.34
COMPILER_PATH=c:/mingw/mingw-10.1.0-64-bit/bin/../libexec/gcc/x86_64-w64-mingw32/10.1.0/;c:/mingw/mingw-10.1.0-64-bit/bin/../libexec/gcc/;c:/mingw/mingw-10.1.0-64-bit/bin/../lib/gcc/x86_64-w64-mingw32/10.1.0/../../../../x86_64-w64-mingw32/bin/
LIBRARY_PATH=c:/mingw/mingw-10.1.0-64-bit/bin/../lib/gcc/x86_64-w64-mingw32/10.1.0/;c:/mingw/mingw-10.1.0-64-bit/bin/../lib/gcc/;c:/mingw/mingw-10.1.0-64-bit/bin/../lib/gcc/x86_64-w64-mingw32/10.1.0/../../../../x86_64-w64-mingw32/lib/../lib/;c:/mingw/mingw-10.1.0-64-bit/bin/../lib/gcc/x86_64-w64-mingw32/10.1.0/../../../../lib/;c:/mingw/mingw-10.1.0-64-bit/bin/../lib/gcc/x86_64-w64-mingw32/10.1.0/../../../../x86_64-w64-mingw32/lib/;c:/mingw/mingw-10.1.0-64-bit/bin/../lib/gcc/x86_64-w64-mingw32/10.1.0/../../../
COLLECT_GCC_OPTIONS='-v' '-o' 'CMakeFiles\cmTC_a01cd.dir\CMakeCCompilerABI.c.obj' '-c' '-mtune=generic' '-march=x86-64'
Linking C executable cmTC_a01cd.exe
"C:\Program Files\CMake\bin\cmake.exe" -E cmake_link_script CMakeFiles\cmTC_a01cd.dir\link.txt --verbose=1
"C:\Program Files\CMake\bin\cmake.exe" -E rm -f CMakeFiles\cmTC_a01cd.dir/objects.a
CMAKE_AR-NOTFOUND cr CMakeFiles\cmTC_a01cd.dir/objects.a #CMakeFiles\cmTC_a01cd.dir\objects1.rsp
Error running link command: The system cannot find the file specified
mingw32-make[1]: *** [CMakeFiles\cmTC_a01cd.dir\build.make:107: cmTC_a01cd.exe] Error 2
mingw32-make[1]: Leaving directory 'C:/Libraries/Projects/CMakeTest/build/MinGW-10.1.0-64-bit/debug/CMakeFiles/CMakeTmp'
mingw32-make: *** [makefile:140: cmTC_a01cd/fast] Error 2
Determining if the C compiler works failed with the following output:
Change Dir: C:/Libraries/Projects/CMakeTest/build/MinGW-10.1.0-64-bit/debug/CMakeFiles/CMakeTmp
Run Build Command(s):C:/MinGW/MinGW-10.1.0-64-bit/bin/mingw32-make.exe cmTC_f77ee/fast && C:/MinGW/MinGW-10.1.0-64-bit/bin/mingw32-make.exe -f CMakeFiles\cmTC_f77ee.dir\build.make CMakeFiles/cmTC_f77ee.dir/build
mingw32-make[1]: Entering directory 'C:/Libraries/Projects/CMakeTest/build/MinGW-10.1.0-64-bit/debug/CMakeFiles/CMakeTmp'
Building C object CMakeFiles/cmTC_f77ee.dir/testCCompiler.c.obj
C:\MinGW\MinGW-10.1.0-64-bit\bin\x86_64-w64-mingw32-gcc.exe -o CMakeFiles\cmTC_f77ee.dir\testCCompiler.c.obj -c C:\Libraries\Projects\CMakeTest\build\MinGW-10.1.0-64-bit\debug\CMakeFiles\CMakeTmp\testCCompiler.c
Linking C executable cmTC_f77ee.exe
"C:\Program Files\CMake\bin\cmake.exe" -E cmake_link_script CMakeFiles\cmTC_f77ee.dir\link.txt --verbose=1
"C:\Program Files\CMake\bin\cmake.exe" -E rm -f CMakeFiles\cmTC_f77ee.dir/objects.a
CMAKE_AR-NOTFOUND cr CMakeFiles\cmTC_f77ee.dir/objects.a #CMakeFiles\cmTC_f77ee.dir\objects1.rsp
Error running link command: The system cannot find the file specified
mingw32-make[1]: *** [CMakeFiles\cmTC_f77ee.dir\build.make:108: cmTC_f77ee.exe] Error 2
mingw32-make[1]: Leaving directory 'C:/Libraries/Projects/CMakeTest/build/MinGW-10.1.0-64-bit/debug/CMakeFiles/CMakeTmp'
mingw32-make: *** [makefile:140: cmTC_f77ee/fast] Error 2
My PATH and complete command line used:
Path:
C:\Windows\system32;C:\Windows;C:\Windows\System32\Wbem;C:\Windows\System32\WindowsPowerShell\v1.0\;C:\Windows\System32\OpenSSH\;C:\Program Files (x86)\QuickTime\QTSystem\;C:\Program Files\MATLAB\R2019b\bin;C:\Program Files\Microsoft VS Code\bin;C:\Program Files\CMake\bin;C:\MinGW\MinGW-10.1.0-64-bit\bin;C:\Users\gvcal\AppData\Local\Microsoft\WindowsApps;
Command line:
"C:\Program Files\CMake\bin\cmake.EXE" -Hc:/Libraries/Projects/CMakeTest -Bc:/Libraries/Projects/CMakeTest/build -G "MinGW Makefiles"
I think this may be a bug with CMake and MinGW Makefiles. Still not entirely sure what it is.
Anyways, I switched to the Ninja build system (https://ninja-build.org/) and all is working fine now.
I would like to be able to import targets from an installed library but
when using:
install(TARGETS
foobar
EXPORT foobarLibTargets
LIBRARY DESTINATION lib)
cmake generates a foobarLibTargets.cmake containing an absolute path:
set_target_properties(foobar PROPERTIES
IMPORTED_LOCATION_NOCONFIG "/where/I/happened/to/build/libfoobar.so"
IMPORTED_SONAME_NOCONFIG "libfoobar.so"
)
Such that a build using the imported target from the installation will fail as the path does not exist.
Q How can I get it to use the correct relative location instead?
This would be equivalent to:
set_target_properties(foobar PROPERTIES
IMPORTED_LOCATION_NOCONFIG "#PACKAGE_LIBRARY_INSTALL_DIR#/libfoobar.so")
If I look at another project which does something similar but works it has:
set_target_properties(foobar PROPERTIES
IMPORTED_LOCATION_RELEASE "${_IMPORT_PREFIX}/lib/libfoobar.so"
IMPORTED_SONAME_RELEASE "libfoobar.so"
)
Here are some example files that reproduce the issue:
CMakeLists.txt:
cmake_minimum_required(VERSION 3.7)
project(FOOBAR VERSION 1.2.3)
set(VERSION 1.2.3)
set(CMAKE_INSTALL_RPATH "$ORIGIN/../lib:$ORIGIN/")
set(CMAKE_INSTALL_PREFIX "/opt/foobar" CACHE PATH "Install path prefix" FORCE)
add_library(foobar SHARED
foobar.cpp
)
set(CPACK_INCLUDE_TOPLEVEL_DIRECTORY 0)
set(CPACK_PACKAGE_NAME "foobar")
set(CPACK_PACKAGE_VERSION ${VERSION})
set(CPACK_PACKAGING_INSTALL_PREFIX ${CMAKE_INSTALL_PREFIX})
set(CPACK_PACKAGE_FILE_NAME "${CPACK_PACKAGE_NAME}-${CPACK_PACKAGE_VERSION}")
include(CPack)
# Indicate the content of the distribution pakcages
install(FILES
${CMAKE_SOURCE_DIR}/foobar.h
DESTINATION include
)
install(TARGETS
foobar
EXPORT foobarLibTargets
LIBRARY DESTINATION lib)
include(CMakePackageConfigHelpers)
set(ConfigFileInstallDir lib/cmake/foobar)
set(INCLUDE_INSTALL_DIR include)
set(LIBRARY_INSTALL_DIR lib)
message(STATUS "CMAKE_INSTALL_PREFIX=${CMAKE_INSTALL_PREFIX}")
configure_package_config_file(foobarConfig.cmake.in
"${CMAKE_BINARY_DIR}/foobarConfig.cmake"
INSTALL_DESTINATION "${ConfigFileInstallDir}"
PATH_VARS INCLUDE_INSTALL_DIR LIBRARY_INSTALL_DIR)
write_basic_package_version_file(
"${CMAKE_BINARY_DIR}/foobarConfigVersion.cmake"
VERSION "${VERSION}"
COMPATIBILITY ExactVersion)
export(EXPORT foobarLibTargets
FILE "${CMAKE_CURRENT_BINARY_DIR}/foobarLibTargets.cmake")
install(EXPORT foobarLibTargets
FILE foobarTargets.cmake
DESTINATION lib/cmake)
install(FILES
"${CMAKE_CURRENT_BINARY_DIR}/foobarConfig.cmake"
"${CMAKE_CURRENT_BINARY_DIR}/foobarConfigVersion.cmake"
"${CMAKE_CURRENT_BINARY_DIR}/foobarLibTargets.cmake"
DESTINATION "${ConfigFileInstallDir}")
foobarConfig.cmake.in:
set(FOOBAR_VERSION #VERSION#)
#PACKAGE_INIT#
set_and_check(FOOBAR_INCLUDE_DIR "#PACKAGE_INCLUDE_INSTALL_DIR#")
set_and_check(FOOBAR_LIBRARY "#PACKAGE_LIBRARY_INSTALL_DIR#/libfoobar.so")
set_and_check(FOOBAR_LIBRARY_DIR "#PACKAGE_LIBRARY_INSTALL_DIR#")
include("${CMAKE_CURRENT_LIST_DIR}/foobarLibTargets.cmake")
# workaround - correct absolute path in the above
# this shouldn't be necessary (hence this question)
#set_target_properties(foobar PROPERTIES
# IMPORTED_LOCATION_NOCONFIG "#PACKAGE_LIBRARY_INSTALL_DIR#/libfoobar.so"
#)
foobar.h:
void hello();
foobar.cpp:
#include <iostream>
void hello() {
std::cerr << "hello world\n";
}
useFoo.cmake (a CMakeLists.txt for an example project using the installed library):
cmake_minimum_required(VERSION 3.7)
project(useFoo VERSION 1.2.3)
set(VERSION 1.2.3)
find_package(foobar)
file(GENERATE OUTPUT foobar-gen CONTENT "<TARGET_FILE:foobar>=$<TARGET_FILE:foobar>\n")
message(STATUS "FOOBAR_LIBRARY_DIR=${FOOBAR_LIBRARY_DIR}")
message(STATUS "FOOBAR_INCLUDE_DIR=${FOOBAR_INCLUDE_DIR}")
build.sh (build and use the installation package):
#!/bin/sh
rm -rf target
mkdir target
cd target
cmake .. &&
make &&
cpack -G TGZ
if [ $? -ne 0 ]; then
echo "doh!"
exit 1
fi
cd ..
rm -rf install
mkdir install
cd install
tar -xvzf ../target/foobar-1.2.3.tar.gz
cp ../useFoo.cmake CMakeLists.txt
export CMAKE_PREFIX_PATH=`pwd`/opt/foobar/lib/cmake:`pwd`/opt/foobar/lib/cmake/foobar
cmake .
if [ $? -ne 0 ]; then
echo "doh!"
exit 1
fi
cat foobar-gen
The output of cat foobar-gen is:
<TARGET_FILE:foobar>=/where/I/happened/to/build/libfoobar.so
I would like it to be:
<TARGET_FILE:foobar>=/where/I/actually/installed/libfoobar.so
Which it becomes if I uncomment the workaround.
Is there a way which avoids the workaround?
The related question - Strange issue with variables in a config-file cmake package - has similar code which both reproduces this issue and adds another one on top.
The main issue is that the two files foobarLibTargets.cmake and foobarTargets.cmake were both installed and the wrong one was picked up.
You will find below an improved project along with remarks to better organize the build system.
ChangeLog summarizing edits
2019-05-25
Create GitHub project to streamline reuse and adaptation. See https://github.com/jcfr/stackoverflow-56135785-answer
Rename project and source directory from foobar to FooBarLib, update Suggestions section accordingly
Improve build.sh
Updated suggestions (CPACK_PACKAGING_INSTALL_PREFIX should be absolute)
RPM:
Add support for building RPM package using make package
Update build.sh to display content of RPM package
Remarks
Two config files should be generated:
one for the build tree: this allow user of your project to directly build against your project and import targets
one for the install tree (which also end up being packaged)
Do not force the value of CMAKE_INSTALL_PREFIX
CPACK_PACKAGING_INSTALL_PREFIX should NOT be set to an absolute directory
For sake of consistency, use foobarTargets instead of foobarLibTargets
<projecname_uc> placeholder used below correspond to the name of the project upper-cased (ABC instead of abc)
To allow configuring your project when vendorized along other one, prefer variable with <projecname_uc>_. This means <projecname_uc>_INSTALL_LIBRARY_DIR is better than LIBRARY_INSTALL_DIR.
To allow user of the project to configure *_INSTALL_DIR variables, wrap them around if(DEFINED ...)
Consistently use variables (e.g LIBRARY_INSTALL_DIR should always be used instead of lib)
Prefer naming variable <projecname_uc>_INSTALL_*_DIR instead of <projecname_uc>_*_INSTALL_DIR, it make it easier to know the purpose of the variable when reading the code.
Since version is already associated with the project, there is no need to set VERSION variable. Instead, you can use PROJECT_VERSION or FOOBAR_VERSION
If starting a new project, prefer the most recent CMake version. CMake 3.13 instead of CMake 3.7
Introduced variable <projecname_uc>_INSTALL_CONFIG_DIR
<project_name>Targets.cmake should not be installed using install(FILES ...), it is already associated with an install rule
conditionally set CMAKE_INSTALL_RPATH, it is valid only on Linux
<project_name>Config.cmake.in:
there is no need to set FOOBAR_LIBRARY, this information is already associated with the exported foobar target
FOOBAR_LIBRARY_DIR is also not needed, this information is already associated with the exported foobar target
instead of setting FOOBAR_INCLUDE_DIR, the command target_include_directories should be used
remove setting of FOOBAR_VERSION, the generate version file already takes care of setting the version.
always specify ARCHIVE, LIBRARY and RUNTIME when declaring install rules for target. It avoid issue when switching library type. One less thing to think about.
always specify component with your install rule. It allows user of your project to selectively install part of it only development component or only runtime one, ...
initializing CMAKE_BUILD_TYPE is also important, it ensures the generated Targets file are associated with a configuration (instead of having the suffix -noconfig.cmake)
Suggested changes
Generally speaking, I recommend to have a source tree, a build tree and install tree. The files posted below assumed the following layout:
./build.sh
./FooBarLib/FooBarLibConfig.cmake.in
./FooBarLib/CMakeLists.txt
./FooBarLib/foobar.cpp
./FooBarLib/foobar.h
./FooBarLib-build
./FooBarLib-install
./useFoo/CMakeLists.txt
./useFoo-build
build.sh
#!/bin/bash
set -xeu
set -o pipefail
script_dir=$(cd $(dirname $0) || exit 1; pwd)
project_name=FooBarLib
archive_name=${project_name}
# cleanup ${project_name}-build
cd $script_dir
rm -rf ${project_name}-build
mkdir ${project_name}-build
cd ${project_name}-build
# configure, build and package ${project_name}
cmake ../${project_name}
make
make package # equivalent to running "cpack -G TGZ" and "cmake -G RPM"
# extract ${project_name} archive
cd $script_dir
rm -rf ${project_name}-install
mkdir ${project_name}-install
cd ${project_name}-install
tar -xvzf ../${project_name}-build/${archive_name}-1.2.3.tar.gz
# cleanup useFoo-build
cd $script_dir
rm -rf useFoo-build
mkdir useFoo-build
cd useFoo-build
cpack_install_prefix=/opt
# configure useFoo
cmake -D${project_name}_DIR=$script_dir/${project_name}-install${cpack_install_prefix}/lib/cmake/${project_name}/ ../useFoo
cat foobar-gen
# display content of RPM. If command "rpmbuild" is available, RPM package is expected.
if command -v rpmbuild &> /dev/null; then
rpm -qlp $script_dir/${project_name}-build/${archive_name}-1.2.3.rpm
fi
FooBarLib/CMakeLists.txt
cmake_minimum_required(VERSION 3.13)
project(FooBarLib VERSION 1.2.3)
if(UNIX AND NOT APPLE)
set(CMAKE_INSTALL_RPATH "$ORIGIN/../lib:$ORIGIN/")
endif()
#------------------------------------------------------------------------------
# Set a default build type if none was specified
if(NOT CMAKE_BUILD_TYPE AND NOT CMAKE_CONFIGURATION_TYPES)
message(STATUS "Setting build type to 'Release' as none was specified.")
set(CMAKE_BUILD_TYPE "Release" CACHE STRING "Choose the type of build." FORCE)
mark_as_advanced(CMAKE_BUILD_TYPE)
# Set the possible values of build type for cmake-gui
set_property(CACHE CMAKE_BUILD_TYPE PROPERTY STRINGS "Debug" "Release" "MinSizeRel" "RelWithDebInfo")
endif()
#------------------------------------------------------------------------------
# This variable controls the prefix used to generate the following files:
# <export_config_name>ConfigVersion.cmake
# <export_config_name>Config.cmake
# <export_config_name>Targets.cmake
# and it also used to initialize FOOBARLIB_INSTALL_CONFIG_DIR value.
set(export_config_name ${PROJECT_NAME})
#------------------------------------------------------------------------------
if(NOT DEFINED FOOBARLIB_INSTALL_INCLUDE_DIR)
set(FOOBARLIB_INSTALL_INCLUDE_DIR include)
endif()
if(NOT DEFINED FOOBARLIB_INSTALL_BIN_DIR)
set(FOOBARLIB_INSTALL_BIN_DIR bin)
endif()
if(NOT DEFINED FOOBARLIB_INSTALL_LIBRARY_DIR)
set(FOOBARLIB_INSTALL_LIBRARY_DIR lib)
endif()
if(NOT DEFINED FOOBARLIB_INSTALL_CONFIG_DIR)
set(FOOBARLIB_INSTALL_CONFIG_DIR ${FOOBARLIB_INSTALL_LIBRARY_DIR}/cmake/${export_config_name})
endif()
#------------------------------------------------------------------------------
set(headers
foobar.h
)
# Install rule for headers
install(
FILES ${headers}
DESTINATION ${FOOBARLIB_INSTALL_INCLUDE_DIR}
COMPONENT Development
)
#------------------------------------------------------------------------------
add_library(foobar SHARED
foobar.cpp
)
target_include_directories(foobar
PUBLIC
$<BUILD_INTERFACE:${FooBarLib_SOURCE_DIR}>
$<INSTALL_INTERFACE:${FOOBARLIB_INSTALL_INCLUDE_DIR}>
)
install(
TARGETS foobar
EXPORT ${export_config_name}Targets
ARCHIVE DESTINATION ${FOOBARLIB_INSTALL_LIBRARY_DIR} COMPONENT Development
LIBRARY DESTINATION ${FOOBARLIB_INSTALL_LIBRARY_DIR} COMPONENT RuntimeLibraries
RUNTIME DESTINATION ${FOOBARLIB_INSTALL_BIN_DIR} COMPONENT RuntimeLibraries
)
#------------------------------------------------------------------------------
# Configure <export_config_name>ConfigVersion.cmake common to build and install tree
include(CMakePackageConfigHelpers)
set(config_version_file ${PROJECT_BINARY_DIR}/${export_config_name}ConfigVersion.cmake)
write_basic_package_version_file(
${config_version_file}
VERSION "${FooBarLib_VERSION}"
COMPATIBILITY ExactVersion
)
#------------------------------------------------------------------------------
# Export '<export_config_name>Targets.cmake' for a build tree
export(
EXPORT ${PROJECT_NAME}Targets
FILE "${CMAKE_CURRENT_BINARY_DIR}/${export_config_name}Targets.cmake"
)
# Configure '<export_config_name>Config.cmake' for a build tree
set(build_config ${CMAKE_BINARY_DIR}/${export_config_name}Config.cmake)
configure_package_config_file(
${export_config_name}Config.cmake.in
${build_config}
INSTALL_DESTINATION "${PROJECT_BINARY_DIR}"
)
#------------------------------------------------------------------------------
# Export '<export_config_name>Targets.cmake' for an install tree
install(
EXPORT ${export_config_name}Targets
FILE ${export_config_name}Targets.cmake
DESTINATION ${FOOBARLIB_INSTALL_CONFIG_DIR}
)
set(install_config ${PROJECT_BINARY_DIR}/CMakeFiles/${export_config_name}Config.cmake)
configure_package_config_file(
${export_config_name}Config.cmake.in
${install_config}
INSTALL_DESTINATION ${FOOBARLIB_INSTALL_CONFIG_DIR}
)
# Install config files
install(
FILES ${config_version_file} ${install_config}
DESTINATION "${FOOBARLIB_INSTALL_CONFIG_DIR}"
)
#------------------------------------------------------------------------------
# Generate package
set(CPACK_INCLUDE_TOPLEVEL_DIRECTORY 0)
set(CPACK_PACKAGE_NAME "${PROJECT_NAME}")
set(CPACK_PACKAGE_VERSION ${PROJECT_VERSION})
set(CPACK_PACKAGE_FILE_NAME "${CPACK_PACKAGE_NAME}-${CPACK_PACKAGE_VERSION}")
# Setting this variable also impacts the layout of TGZ.
set(CPACK_PACKAGING_INSTALL_PREFIX "/opt")
# Setting CPACK_SOURCE_* and CPACK_GENERATOR allow to have "make package" generates
# the expected archive.
# Disable source generator enabled by default
set(CPACK_SOURCE_TBZ2 OFF CACHE BOOL "Enable to build TBZ2 source packages" FORCE)
set(CPACK_SOURCE_TGZ OFF CACHE BOOL "Enable to build TGZ source packages" FORCE)
set(CPACK_SOURCE_TZ OFF CACHE BOOL "Enable to build TZ source packages" FORCE)
# Select generators
if(UNIX AND NOT APPLE)
set(CPACK_GENERATOR "TGZ")
find_program(RPMBUILD_PATH rpmbuild)
if(RPMBUILD_PATH)
list(APPEND CPACK_GENERATOR "RPM")
endif()
elseif(APPLE)
# ...
endif()
include(CPack)
FooBarLib/FooBarLibConfig.cmake.in
#PACKAGE_INIT#
set(export_config_name "#export_config_name#")
set_and_check(${export_config_name}_TARGETS "${CMAKE_CURRENT_LIST_DIR}/${export_config_name}Targets.cmake")
include(${${export_config_name}_TARGETS})
useFoo/CMakeLists.txt
cmake_minimum_required(VERSION 3.13)
project(useFoo VERSION 1.2.3)
find_package(FooBarLib REQUIRED)
file(GENERATE OUTPUT foobar-gen CONTENT "<TARGET_FILE:foobar>=$<TARGET_FILE:foobar>\n")
get_target_property(foobar_INCLUDE_DIR foobar INTERFACE_INCLUDE_DIRECTORIES)
message(STATUS "foobar_INCLUDE_DIR=${foobar_INCLUDE_DIR}")
get_target_property(imported_location foobar IMPORTED_LOCATION_RELEASE)
get_filename_component(foobar_LIBRARY_DIR ${imported_location} DIRECTORY)
message(STATUS "foobar_LIBRARY_DIR=${foobar_LIBRARY_DIR}")
Output of build.sh
./build.sh
+ set -o pipefail
+++ dirname ./build.sh
++ cd .
++ pwd
+ script_dir=/tmp/stackoverflow-56135785-answer
+ project_name=FooBarLib
+ archive_name=FooBarLib
+ cd /tmp/stackoverflow-56135785-answer
+ rm -rf FooBarLib-build
+ mkdir FooBarLib-build
+ cd FooBarLib-build
+ cmake ../FooBarLib
-- The C compiler identification is GNU 4.8.5
-- The CXX compiler identification is GNU 4.8.5
-- Check for working C compiler: /usr/bin/cc
-- Check for working C compiler: /usr/bin/cc -- works
-- Detecting C compiler ABI info
-- Detecting C compiler ABI info - done
-- Detecting C compile features
-- Detecting C compile features - done
-- Check for working CXX compiler: /usr/bin/c++
-- Check for working CXX compiler: /usr/bin/c++ -- works
-- Detecting CXX compiler ABI info
-- Detecting CXX compiler ABI info - done
-- Detecting CXX compile features
-- Detecting CXX compile features - done
-- Setting build type to 'Release' as none was specified.
-- Configuring done
-- Generating done
-- Build files have been written to: /tmp/stackoverflow-56135785-answer/FooBarLib-build
+ make
Scanning dependencies of target foobar
[ 50%] Building CXX object CMakeFiles/foobar.dir/foobar.cpp.o
[100%] Linking CXX shared library libfoobar.so
[100%] Built target foobar
+ make package
[100%] Built target foobar
Run CPack packaging tool...
CPack: Create package using TGZ
CPack: Install projects
CPack: - Run preinstall target for: FooBarLib
CPack: - Install project: FooBarLib
CPack: Create package
CPack: - package: /tmp/stackoverflow-56135785-answer/FooBarLib-build/FooBarLib-1.2.3.tar.gz generated.
CPack: Create package using RPM
CPack: Install projects
CPack: - Run preinstall target for: FooBarLib
CPack: - Install project: FooBarLib
CPack: Create package
-- CPackRPM:Debug: Using CPACK_RPM_ROOTDIR=/tmp/stackoverflow-56135785-answer/FooBarLib-build/_CPack_Packages/Linux/RPM
CPackRPM: Will use GENERATED spec file: /tmp/stackoverflow-56135785-answer/FooBarLib-build/_CPack_Packages/Linux/RPM/SPECS/foobarlib.spec
CPack: - package: /tmp/stackoverflow-56135785-answer/FooBarLib-build/FooBarLib-1.2.3.rpm generated.
+ cd /tmp/stackoverflow-56135785-answer
+ rm -rf FooBarLib-install
+ mkdir FooBarLib-install
+ cd FooBarLib-install
+ tar -xvzf ../FooBarLib-build/FooBarLib-1.2.3.tar.gz
opt/
opt/include/
opt/include/foobar.h
opt/lib/
opt/lib/libfoobar.so
opt/lib/cmake/
opt/lib/cmake/FooBarLib/
opt/lib/cmake/FooBarLib/FooBarLibTargets.cmake
opt/lib/cmake/FooBarLib/FooBarLibTargets-release.cmake
opt/lib/cmake/FooBarLib/FooBarLibConfigVersion.cmake
opt/lib/cmake/FooBarLib/FooBarLibConfig.cmake
+ cd /tmp/stackoverflow-56135785-answer
+ rm -rf useFoo-build
+ mkdir useFoo-build
+ cd useFoo-build
+ cpack_install_prefix=/opt
+ cmake -DFooBarLib_DIR=/tmp/stackoverflow-56135785-answer/FooBarLib-install/opt/lib/cmake/FooBarLib/ ../useFoo
-- The C compiler identification is GNU 4.8.5
-- The CXX compiler identification is GNU 4.8.5
-- Check for working C compiler: /usr/bin/cc
-- Check for working C compiler: /usr/bin/cc -- works
-- Detecting C compiler ABI info
-- Detecting C compiler ABI info - done
-- Detecting C compile features
-- Detecting C compile features - done
-- Check for working CXX compiler: /usr/bin/c++
-- Check for working CXX compiler: /usr/bin/c++ -- works
-- Detecting CXX compiler ABI info
-- Detecting CXX compiler ABI info - done
-- Detecting CXX compile features
-- Detecting CXX compile features - done
-- foobar_INCLUDE_DIR=/tmp/stackoverflow-56135785-answer/FooBarLib-install/opt/include
-- foobar_LIBRARY_DIR=/tmp/stackoverflow-56135785-answer/FooBarLib-install/opt/lib
-- Configuring done
-- Generating done
-- Build files have been written to: /tmp/stackoverflow-56135785-answer/useFoo-build
+ cat foobar-gen
<TARGET_FILE:foobar>=/tmp/stackoverflow-56135785-answer/FooBarLib-install/opt/lib/libfoobar.so
+ command -v rpmbuild
+ rpm -qlp /tmp/stackoverflow-56135785-answer/FooBarLib-build/FooBarLib-1.2.3.rpm
/opt
/opt/include
/opt/include/foobar.h
/opt/lib
/opt/lib/cmake
/opt/lib/cmake/FooBarLib
/opt/lib/cmake/FooBarLib/FooBarLibConfig.cmake
/opt/lib/cmake/FooBarLib/FooBarLibConfigVersion.cmake
/opt/lib/cmake/FooBarLib/FooBarLibTargets-release.cmake
/opt/lib/cmake/FooBarLib/FooBarLibTargets.cmake
/opt/lib/libfoobar.so
Only after instrumenting the source of cmake itself was I finally able to track this down.
The export and install commands are both capable of generating cmake files for targets.
The export command e.g.:
export(EXPORT foobarLibTargets
FILE "${CMAKE_CURRENT_BINARY_DIR}/foobarLibTargets.cmake")
creates a Targets.cmake referencing the build tree.
The install command e.g.:
install(EXPORT foobarLibTargets
FILE foobarTargets.cmake
DESTINATION lib/cmake)
creates a Targets.cmake referencing the relocatable install location.
This is essentially what #J-Christophe meant by saying that two files were installed and the wrong one was picked up.
I had wrongly assumed that the install command was only responsible for installing files and the export command was only responsible for generating them.
The documentation makes sense now
export(EXPORT [NAMESPACE ] [FILE ])
The file created by this command is specific to the build tree and
should never be installed. See the install(EXPORT) command to export
targets from an installation tree.
The workaround I had previously is no longer necesary.
For reference this was to explicitly set the correct location in the package's Config.cmake as in:
set(FOOBAR_VERSION #VERSION#)
#PACKAGE_INIT#
set_and_check(FOOBAR_INCLUDE_DIR "#PACKAGE_INCLUDE_INSTALL_DIR#")
set_and_check(FOOBAR_LIBRARY "#PACKAGE_LIBRARY_INSTALL_DIR#/libfoobar.so")
set_and_check(FOOBAR_LIBRARY_DIR "#PACKAGE_LIBRARY_INSTALL_DIR#")
include("${CMAKE_CURRENT_LIST_DIR}/foobarLibTargets.cmake")
# workaround - correct absolute path in the above
# this shouldn't be necessary!
set_target_properties(foobar PROPERTIES
IMPORTED_LOCATION_NOCONFIG "#PACKAGE_LIBRARY_INSTALL_DIR#/libfoobar.so"
)
Most of the solutions here are misleading. It's by design working that way: https://github.com/Kitware/CMake/blob/f46c67de0e16293a40bbbade18aa7cee9edb02b0/Source/cmExportInstallFileGenerator.cxx#L184-L192
So if the DESTINATION in the install(EXPORT ...) statement is an absolute path, then hardcode it as absolute path in the exported package config files. Otherwise, generate the path dynamically using _IMPORT_PREFIX.
I want to build gui application with SDL2. I link SDL2 libraries(libSDL2.dll.a and libSDL2main.a) but I don't know how a can apply -mwindows flag to my application. Without him .exe file of my application doesn't show window (executing have not any effect). I use MinGW-w64 my OS is Windows 10. In command line I can do this like here (see section B). How I can apply this flag with usage cmake? Console application works fine.
I try next variant but it doesn't work.
cmake -G "MinGW Makefiles" -D CMAKE_C_COMPILER=gcc -D CMAKE_CXX_COMPILER=g++ -D CMAKE_EXE_LINKER_FLAGS="-mwindows"
cmake -G "MinGW Makefiles" -D CMAKE_C_COMPILER=gcc -D CMAKE_CXX_COMPILER=g++ -D CMAKE_CXX_FLAGS="-mwindows"
Also in CMakeLists.txt I try do like this
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -mwindows")
You can pass WIN32 argument to add_executable and CMake will do this for you:
add_executable(target_name WIN32 ${sources})
I basically copy-pasted the stuff, which CLion executes in the command line, and it worked:
$ cmake DCMAKE_BUILD_TYPE=Debug -G "CodeBlocks - MinGW Makefiles" ../
$ cmake --build ./ --target target_name -j 6
[ 50%] Building CXX object CMakeFiles/target_name.dir/main.cpp.obj
[100%] Linking CXX executable target_name.exe
[100%] Built target tree_traverse
After this the executable target_name.exe appeared in the directory.