I'm using CLion 1.2 to build an embedded C project for an STM32 target. Cross compilation using GNU ARM tools works well, however, I would like to run arm-none-eabi-size after the executable file has been built, and have the output of that command be printed to the build output window.
I have had a thorough look at the add_custom_command macro, however, I do not intend on generating an output file, which is what the macro appears to do.
Below is the CMakeLists.txt that I am using in the project:
cmake_minimum_required(VERSION 3.3)
include(CMakeForceCompiler)
project(rtos_clion)
# -------------------------------------------------------------------
set(CMAKE_SYSTEM_PROCESSOR cortex-m0)
SET(CMAKE_SYSTEM_NAME Generic)
# Target Environment
SET(CMAKE_FIND_ROOT_PATH "C:/Program Files (x86)/GNU Tools ARM Embedded/4.9 2015q2")
# Cross compiler
CMAKE_FORCE_C_COMPILER(arm-none-eabi-gcc GNU)
CMAKE_FORCE_CXX_COMPILER(arm-none-eabi-g++ GNU)
# Executable type
set(CMAKE_EXECUTABLE_SUFFIX ".elf")
# Compiler flags
set(ARM_FLAGS "-mcpu=cortex-m0 -mthumb -Os")
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${ARM_FLAGS} -std=gnu++11 -fabi-version=0 -fno-exceptions -fno-rtti -fno-use-cxa-atexit -fno-threadsafe-statics -ffunction-sections -g")
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -std=gnu11 ${ARM_FLAGS} -ffunction-sections -fmessage-length=0 -fsigned-char -fdata-sections -ffreestanding -fno-move-loop-invariants -Wall -Wextra -g")
set(CMAKE_EXE_LINKER_FLAGS "${ARM_FLAGS} -g -Wl,--library-path=\"${PROJECT_SOURCE_DIR}\" -T mem.ld -T libs.ld -T sections.ld -Xlinker --gc-sections -Wl,-Map=${PROJECT_NAME}.map --specs=nano.specs")
set(CMAKE_C_LINK_EXECUTABLE "<CMAKE_C_COMPILER> <LINK_FLAGS> -o <TARGET> <OBJECTS>")
set(CMAKE_CXX_LINK_EXECUTABLE "<CMAKE_CXX_COMPILER> <LINK_FLAGS> -o <TARGET> <OBJECTS>")
# -------------------------------------------------------------------
# Global definitions
add_definitions(-DDEBUG -DUSE_FULL_ASSERT -DSTM32F051x8 -DHSE_VALUE=8000000)
include_directories(
# My include directories
)
set(SOURCE_FILES
# My source files
)
add_executable(${PROJECT_NAME} ${SOURCE_FILES})
# search for programs in the build host directories
set(CMAKE_FIND_ROOT_PATH_MODE_PROGRAM NEVER)
set(CMAKE_FIND_ROOT_PATH_MODE_LIBRARY ONLY)
set(CMAKE_FIND_ROOT_PATH_MODE_INCLUDE ONLY)
This is what arm-none-eabi-size prints when executed in a console:
$arm-none-eabi-size --format=berkeley "rtos_clion.elf"
text data bss dec hex filename
32840 308 7796 40944 9ff0 rtos_clion.elf
How would I have that run and have that output displayed in the build window?
Thanks!
Just use TARGET flow of add_custom_command:
add_custom_command(TARGET ${PROJECT_NAME} POST_BUILD
COMMAND arm-none-eabi-size --format=berkeley "rtos_clion.elf")
The command will be executed after executable has been (re)built.
Even the .elf file can be taken from a variable:
set_target_properties(${TARGET} PROPERTIES SUFFIX ".elf")
add_custom_command(TARGET ${MAIN_TARGET} POST_BUILD
COMMAND arm-none-eabi-size --format=berkeley --totals "$<TARGET_FILE:${TARGET}>"
COMMENT "Invoking: Cross ARM GNU Print Size")
Related
I am trying to compile CLion Project.
and the CMakeList.txt
set(CMAKE_SYSTEM_NAME Generic)
set(CMAKE_SYSTEM_VERSION 1)
cmake_minimum_required(VERSION 3.23)
# specify cross-compilers and tools
set(CMAKE_C_COMPILER arm-none-eabi-gcc)
set(CMAKE_CXX_COMPILER arm-none-eabi-g++)
set(CMAKE_ASM_COMPILER arm-none-eabi-gcc)
set(CMAKE_AR arm-none-eabi-ar)
set(CMAKE_OBJCOPY arm-none-eabi-objcopy)
set(CMAKE_OBJDUMP arm-none-eabi-objdump)
set(SIZE arm-none-eabi-size)
set(CMAKE_TRY_COMPILE_TARGET_TYPE STATIC_LIBRARY)
# project settings
project(main_board C CXX ASM)
set(CMAKE_CXX_STANDARD 17)
set(CMAKE_C_STANDARD 11)
#Uncomment for hardware floating point
add_compile_definitions(ARM_MATH_CM4;ARM_MATH_MATRIX_CHECK;ARM_MATH_ROUNDING)
add_compile_options(-mfloat-abi=hard -mfpu=fpv4-sp-d16)
add_link_options(-mfloat-abi=hard -mfpu=fpv4-sp-d16)
#Uncomment for software floating point
#add_compile_options(-mfloat-abi=soft)
add_compile_options(-mcpu=cortex-m4 -mthumb -mthumb-interwork)
add_compile_options(-ffunction-sections -fdata-sections -fno-common -fmessage-length=0)
# uncomment to mitigate c++17 absolute addresses warnings
#set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wno-register")
# Enable assembler files preprocessing
add_compile_options($<$<COMPILE_LANGUAGE:ASM>:-x$<SEMICOLON>assembler-with-cpp>)
if ("${CMAKE_BUILD_TYPE}" STREQUAL "Release")
message(STATUS "Maximum optimization for speed")
add_compile_options(-Ofast)
elseif ("${CMAKE_BUILD_TYPE}" STREQUAL "RelWithDebInfo")
message(STATUS "Maximum optimization for speed, debug info included")
add_compile_options(-Ofast -g)
elseif ("${CMAKE_BUILD_TYPE}" STREQUAL "MinSizeRel")
message(STATUS "Maximum optimization for size")
add_compile_options(-Os)
else ()
message(STATUS "Minimal optimization, debug info included")
add_compile_options(-Og -g)
endif ()
include_directories(Core/Inc USB_DEVICE/App USB_DEVICE/Target Drivers/STM32F4xx_HAL_Driver/Inc Drivers/STM32F4xx_HAL_Driver/Inc/Legacy Middlewares/Third_Party/FreeRTOS/Source/include Middlewares/Third_Party/FreeRTOS/Source/CMSIS_RTOS_V2 Middlewares/Third_Party/FreeRTOS/Source/portable/GCC/ARM_CM4F Middlewares/ST/STM32_USB_Device_Library/Core/Inc Middlewares/ST/STM32_USB_Device_Library/Class/CDC/Inc Drivers/CMSIS/Device/ST/STM32F4xx/Include Drivers/CMSIS/Include Middlewares/ST/ARM/DSP/Inc)
include_directories(Core/app/Inc Core/app/protocol Core/bsp/Inc Core/components/algorithm Core/components/algorithm/Include Core/components/controller Core/components/devices Core/components/support)
add_definitions(-DUSE_HAL_DRIVER -DSTM32F407xx -DARM_MATH_CM4 -D__FPU_PRESENT=1U -DARM_MATH_MATRIX_CHECK -DARM_MATH_ROUNDING)
add_definitions(-Wno-attributes) # ignore warning: 'packed' attribute ignored'
file(GLOB_RECURSE SOURCES "startup/*.*" "Library/*.*" "Middlewares/*.*" "Drivers/*.*" "USB_DEVICE/*.*" "Core/*.*")
set(LINKER_SCRIPT ${CMAKE_SOURCE_DIR}/STM32F407IGHx_FLASH.ld)
add_link_options(-Wl,-gc-sections,--print-memory-usage,-Map=${PROJECT_BINARY_DIR}/${PROJECT_NAME}.map)
add_link_options(-mcpu=cortex-m4 -mthumb -mthumb-interwork)
add_link_options(-T ${LINKER_SCRIPT})
add_executable(${PROJECT_NAME}.elf ${SOURCES} ${LINKER_SCRIPT})
set(HEX_FILE ${PROJECT_BINARY_DIR}/${PROJECT_NAME}.hex)
set(BIN_FILE ${PROJECT_BINARY_DIR}/${PROJECT_NAME}.bin)
add_custom_command(TARGET ${PROJECT_NAME}.elf POST_BUILD
COMMAND ${CMAKE_OBJCOPY} -Oihex $<TARGET_FILE:${PROJECT_NAME}.elf> ${HEX_FILE}
COMMAND ${CMAKE_OBJCOPY} -Obinary $<TARGET_FILE:${PROJECT_NAME}.elf> ${BIN_FILE}
COMMENT "Building ${HEX_FILE}
Building ${BIN_FILE}")
As soon as i try to include the arm_math.h and into my CLion Project i get a ton of: main.cpp:(.text+0x23c): undefined reference to glViewport error messages and building my main.cpp in the base dir fails.
As soon as i try to call the function defined in arm_math.h. it will ton of error: undefined reference to 'xxx'
At the same time, another project of mine has the same problem. It cannot use the static library file correctly.
FAILED: main_board.elf
cmd.exe /C "cd . && C:\PROGRA~2\GNUARM~1\102021~1.07\bin\AR19DD~1.EXE -O3 -DNDEBUG -mfloat-abi=hard -mfpu=fpv4-sp-d16 -Wl,-gc-sections,--print-memory-usage,-Map=C:/Users/Cjsah/Desktop/rm/final/main_board/build/main_board.map -mcpu=cortex-m4 -mthumb -mthumb-interwork -T C:/Users/Cjsah/Desktop/rm/final/main_board/STM32F407IGHx_FLASH.ld #CMakeFiles\main_board.elf.rsp -o main_board.elf && cmd.exe /C "cd /D C:\Users\Cjsah\Desktop\rm\final\main_board\build && arm-none-eabi-objcopy -Oihex C:/Users/Cjsah/Desktop/rm/final/main_board/build/main_board.elf C:/Users/Cjsah/Desktop/rm/final/main_board/build/main_board.hex && arm-none-eabi-objcopy -Obinary C:/Users/Cjsah/Desktop/rm/final/main_board/build/main_board.elf C:/Users/Cjsah/Desktop/rm/final/main_board/build/main_board.bin""
c:/progra~2/gnuarm~1/102021~1.07/bin/../lib/gcc/arm-none-eabi/10.3.1/../../../../arm-none-eabi/bin/ld.exe: CMakeFiles/main_board.elf.dir/Core/app/Src/chassis_behaviour.c.obj: in function `chassis_behaviour_control_set':
chassis_behaviour.c:(.text.chassis_behaviour_control_set+0x6c): undefined reference to `arm_sin_f32'
c:/progra~2/gnuarm~1/102021~1.07/bin/../lib/gcc/arm-none-eabi/10.3.1/../../../../arm-none-eabi/bin/ld.exe: CMakeFiles/main_board.elf.dir/Core/app/Src/chassis_task.c.obj: in function `chassis_task':
chassis_task.c:(.text.chassis_task+0x2da): undefined reference to `arm_sin_f32'
c:/progra~2/gnuarm~1/102021~1.07/bin/../lib/gcc/arm-none-eabi/10.3.1/../../../../arm-none-eabi/bin/ld.exe: chassis_task.c:(.text.chassis_task+0x2ec): undefined reference to `arm_cos_f32'
c:/progra~2/gnuarm~1/102021~1.07/bin/../lib/gcc/arm-none-eabi/10.3.1/../../../../arm-none-eabi/bin/ld.exe: CMakeFiles/main_board.elf.dir/Core/app/Src/gimbal_task.c.obj: in function `gimbal_feedback_update.constprop.0':
gimbal_task.c:(.text.gimbal_feedback_update.constprop.0+0x7a): undefined reference to `arm_cos_f32'
c:/progra~2/gnuarm~1/102021~1.07/bin/../lib/gcc/arm-none-eabi/10.3.1/../../../../arm-none-eabi/bin/ld.exe: gimbal_task.c:(.text.gimbal_feedback_update.constprop.0+0x8c): undefined reference to `arm_sin_f32'
It looks like, that CLion just dose not link find the right arm_cortexM4l_math.lib in my own program. if I include it from arm_math.h. Is the problem caused by the compiler or because I wrote fewer statements?
I'm building a LLVM environment on Windows that can work without Microsoft compiler and SDK and without GCC compiler or GNU linker, only LLVM (the official build) and MinGW-w64 runtime.
When compiling this C program with clang compiler and lld linker, and with x86_64-windows-gnu target (MinGW-w64 runtime), it works:
> type c1.c
#include <stdio.h>
int main() {
printf("hello 1\n");
return 0;
}
> clang c1.c -target x86_64-windows-gnu -fuse-ld=lld -o c1.exe
> c1
hello 1
How to achieve the same with CMake? Is there a high level option for CMake to set these flags automatically? Or, when trying to set these flags manually (with CMAKE_EXE_LINKER_FLAGS or CMAKE_C_FLAGS) looks like that it confuses CMake and it still passes some Visual C++ style flags (like /subsystem:console) during linking:
> type CMakeLists.txt
project (P1 C)
cmake_minimum_required(VERSION 3.0)
set (CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -target x86_64-windows-gnu -fuse-ld=lld")
add_executable (c1 c1.c)
> cmake -G Ninja -B build -DCMAKE_C_COMPILER=clang
-- The C compiler identification is Clang 12.0.0 with GNU-like command-line
-- Detecting C compiler ABI info
-- Detecting C compiler ABI info - done
-- Check for working C compiler: C:/Program Files/LLVM/bin/clang.exe - skipped
-- Detecting C compile features
-- Detecting C compile features - done
-- Configuring done
-- Generating done
-- Build files have been written to: C:/build
> cmake --build build
[2/2] Linking C executable c1.exe
FAILED: c1.exe
cmd.exe /C "cd . && C:\PROGRA~1\LLVM\bin\clang.exe -fuse-ld=lld-link -nostartfiles -nostdlib -g -Xclang -gcodeview -O0 -D_DEBUG -D_DLL -D_MT -Xclang --dependent-lib=msvcrtd -target x86_64-windows-gnu -fuse-ld=lld -Xlinker /subsystem:console CMakeFiles/c1.dir/c1.c.obj -o c1.exe -Xlinker /implib:c1.lib -Xlinker /pdb:c1.pdb -Xlinker /version:0.0 -lkernel32 -luser32 -lgdi32 -lwinspool -lshell32 -lole32 -loleaut32 -luuid -lcomdlg32 -ladvapi32 -loldnames && cd ."
lld: error: unable to find library -loldnames
clang: error: linker command failed with
Please see the documentation on toolchains here: https://cmake.org/cmake/help/latest/manual/cmake-toolchains.7.html#cross-compiling-using-clang
Since you're overriding the default Clang target, CMake needs to know about this during compiler detection. By the time you're in the CMakeLists.txt, it is too late. The following clang-x86_64_windows_gnu.cmake toolchain file might work (I can't test it without replicating your environment):
set(CMAKE_C_COMPILER clang)
set(CMAKE_C_COMPILER_TARGET x86_64-windows-gnu)
set(CMAKE_EXE_LINKER_FLAGS_INIT "-fuse-ld=lld")
set(CMAKE_MODULE_LINKER_FLAGS_INIT "-fuse-ld=lld")
set(CMAKE_SHARED_LINKER_FLAGS_INIT "-fuse-ld=lld")
Then your CMakeLists.txt was wrong, it should be:
cmake_minimum_required(VERSION 3.20)
project(P1 LANGUAGES C)
add_executable(c1 c1.c)
Notice the order of the cmake_minimum_required and project commands. They should always be the first two lines in your CMakeLists.txt, in that order.
I am trying to turn off optimizations for the contents of a single project folder. The project is currently using optimization level -O3.
Is there an easy way to do this?
Used tools:
GNU Tools for ARM Embedded Processors (arm-none-eabi-gcc)
gcc version 5.4.1 20160919 (release)
Eclipse IDE for C/C++ Developers
Version: Neon.2 Release (4.6.2)
Build id: 20161208-0600
Edit:
I have an automatically generated makefile for each sub-directory.
Example.
# Automatically-generated file. Do not edit!
# Add inputs and outputs from these tool invocations to the build variables
C_SRCS += \
../App/src/CustomerUnit.c \
OBJS += \
../App/src/CustomerUnit.o \
C_DEPS += \
../App/src/CustomerUnit.d \
# Each subdirectory must supply rules for building sources it contributes
ahuapp/Diagnostics/cag/%.o: ../App/src/%.c
#echo 'Building file: $<'
#echo 'Invoking: Cross ARM GNU C Compiler'
arm-none-eabi-gcc -mcpu=cortex-m3 -mthumb -O3 -fmessage-length=0 -fsigned-char -ffunction-sections -fdata-sections -g3 -D$(M3AppSymbols) -I"../$(M3APPIncludePaths)" -std=gnu11 -MMD -MP -MF"$(#:%.o=%.d)" -MT"$(#)" -c -o "$#" "$<"
#echo 'Finished building: $<'
#echo ' '
So what I want to do, that I don't know, is change the -O3 level to -O0 only for this particular sub directory.
I generated a project by the STMCubeMX and wanted to import this project into Clion.
Here's the CmakeList.txt:
project(ClionTest)
cmake_minimum_required(VERSION 3.8)
add_definitions(-DSTM32F4xx)
file(GLOB_RECURSE USER_SOURCES "Src/*.c")
file(GLOB_RECURSE HAL_SOURCES "Drivers/STM32F4xx_HAL_Driver/Src/*.c")
add_library(CMSIS
startup/startup_stm32f407xx.s)
include_directories(Drivers/CMSIS/Device)
include_directories(Drivers/CMSIS/Device/ST/STM32F4xx/Include)
include_directories(Drivers/CMSIS/Include)
include_directories(Drivers/STM32F4xx_HAL_Driver)
include_directories(Drivers/STM32F4xx_HAL_Driver/Inc)
include_directories(Inc)
include_directories(Middlewares/Third_Party/LwIP/src/include)
add_executable(${PROJECT_NAME}.elf ${USER_SOURCES} ${HAL_SOURCES} ${LINKER_SCRIPT})
target_link_libraries(${PROJECT_NAME}.elf CMSIS)
set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -Wl,-Map=${PROJECT_SOURCE_DIR}/build/${PROJECT_NAME}.map")
set(HEX_FILE ${PROJECT_SOURCE_DIR}/build/${PROJECT_NAME}.hex)
set(BIN_FILE ${PROJECT_SOURCE_DIR}/build/${PROJECT_NAME}.bin)
add_custom_command(TARGET ${PROJECT_NAME}.elf POST_BUILD
COMMAND ${CMAKE_OBJCOPY} -Oihex $<TARGET_FILE:${PROJECT_NAME}.elf> ${HEX_FILE}
COMMAND ${CMAKE_OBJCOPY} -Obinary $<TARGET_FILE:${PROJECT_NAME}.elf> ${BIN_FILE}
COMMENT "Building ${HEX_FILE} \nBuilding ${BIN_FILE}")
And a STM32F4xx.cmake file:
INCLUDE(CMakeForceCompiler)
SET(CMAKE_SYSTEM_NAME Generic)
SET(CMAKE_SYSTEM_VERSION 1)
# specify the cross compiler
#CMAKE_FORCE_C_COMPILER(C:/Program Files (x86)/GNU Tools ARM Embedded/6 2017-q2-update/bin/arm-none-eabi-gcc.exe GNU)
#CMAKE_FORCE_CXX_COMPILER(D:/Lib/arm/bin/arm-none-eabi-g++.exe GNU)
SET(CMAKE_C_COMPILER "C:/Program Files (x86)/GNU Tools ARM Embedded/6 2017-q2-update/bin/arm-none-eabi-gcc.exe")
SET(CMAKE_CXX_COMPILER "C:/Program Files (x86)/GNU Tools ARM Embedded/6 2017-q2-update/bin/arm-none-eabi-g++.exe")
SET(LINKER_SCRIPT ${PROJECT_SOURCE_DIR}/STM32F407VETx_FLASH.ld)
#Uncomment for software floating point
#SET(COMMON_FLAGS "-mcpu=cortex-m4 -mthumb -mthumb-interwork -mfloat-abi=soft -ffunction-sections -fdata-sections -g -fno-common -fmessage-length=0")
SET(COMMON_FLAGS "-mcpu=cortex-m4 -mthumb -mthumb-interwork -mfloat-abi=hard -mfpu=fpv4-sp-d16 -ffunction-sections -fdata-sections -g -fno-common -fmessage-length=0")
SET(CMAKE_CXX_FLAGS_INIT "${COMMON_FLAGS} -std=c++11")
SET(CMAKE_C_FLAGS_INIT "${COMMON_FLAGS} -std=gnu99")
SET(CMAKE_EXE_LINKER_FLAGS_INIT "-Wl,-gc-sections,-M=binary.map -T ${LINKER_SCRIPT}")
I set LINKER_SCRIPT ${PROJECT_SOURCE_DIR}/STM32F407VETx_FLASH.ld
File structure
And the Cmake options is:
Cmake options
When I reload this project, it's not go on well.
c:/progra~2/gnutoo~1/62017-~1/bin/../lib/gcc/arm-none-eabi/6.3.1/../../../../arm-none-eabi/bin/ld.exe: cannot open linker script file
D:/Project/ClionTest/cmake-build-default/CMakeFiles/CMakeTmp/STM32F407VETx_FLASH.ld:
Invalid argument
collect2.exe: error: ld returned 1 exit status
CMakeFiles\cmTC_bf7b4.dir\build.make:96: recipe for target 'cmTC_bf7b4' failed
mingw32-make.exe[1]: *** [cmTC_bf7b4] Error 1
mingw32-make.exe[1]: Leaving directory
'D:/Project/ClionTest/cmake-build-default/CMakeFiles/CMakeTmp'
Makefile:125: recipe for target 'cmTC_bf7b4/fast' failed
mingw32-make.exe: *** [cmTC_bf7b4/fast] Error 2
It seems like the path of ld.exe is not correct,how shoulld I set its path?
And why the path of STM32F407VETx_FLASH.ld it searched is not the path I set?
I'm using Linux, but I've had the a similar issue in regards to being unable to open the linker script.
cannot open linker script file D:/Project/ClionTest/cmake-build-default/CMakeFiles/CMakeTmp/STM32F407VETx_FLASH.ld
After looking for a while at the documentation for target_link_option (which does approximately the same kind of thing as setting a variable directly), I took note of the SHELL: directive, that's stated to:
The set of options is de-duplicated to avoid repetition. While beneficial for individual options, the de-duplication step can break up option groups. For example, -D A -D B becomes -D A B. One may specify a group of options using shell-like quoting along with a SHELL: prefix. The SHELL: prefix is dropped and the rest of the option string is parsed using the separate_arguments() UNIX_COMMAND mode.
By adding it to my command, I managed to get compilation working normally. The result was the following:
set(LINKER_SCRIPT "${CMAKE_SOURCE_DIR}/STM32F303CCTX_FLASH.ld")
set(LINKER_FLAGS "SHELL:-T${LINKER_SCRIPT} -Wl,--gc-sections --specs=nano.specs --specs=nosys.specs")
target_link_options(${PROJECT_BINARY} PRIVATE ${LINKER_FLAGS})
Change this:
SET(CMAKE_EXE_LINKER_FLAGS_INIT "-Wl,-gc-sections,-M=binary.map -T ${LINKER_SCRIPT}")
To:
SET(CMAKE_EXE_LINKER_FLAGS "-Wl,-gc-sections,-M=binary.map -T${LINKER_SCRIPT}")
I have a project with C and ASM (AT&T) source files that needs a linker script. My CMakeLists.txt looks something like this:
cmake_minimum_required(VERSION 2.8.4)
project(proj C ASM-ATT)
file(GLOB SOURCE_FILES *.c *.S)
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -m32 -Wall -g -fno-stack-protector -pedantic")
add_executable(proj ${SOURCE_FILES})
set_target_properties(proj PROPERTIES LINK_FLAGS "-T${proj_SOURCE_DIR}/link.ld -melf_i386")
Strangely enough, building with make VERBOSE=1 reveals the following:
[ 14%] Linking C executable proj
(...)
/usr/bin/cc -m32 -Wall -g -fno-stack-protector -pedantic -T/path/to/link.ld -melf_i386 (all object files)
cc: error: unrecognized command line option '-melf_i386'
It seems that CMake is trying to use /usr/bin/cc as a C linker. I have played around with this and tried several different options (including setting CMAKE_LINKER and CMAKE_EXE_LINK_OPTIONS).
Also note that CMakeCache.txt contains a line saying
CMAKE_LINKER:FILEPATH=/usr/bin/ld
so it obviously is aware of ld and is simply using the C compiler to link the executable.
Any help would be greatly appreciated!
CMake by default invokes the linker indirectly through the compiler executable. The template command for linking executables is set up in the variable CMAKE_LANG_LINK_EXECUTABLE.
To have the compiler pass the flags on to the linker, use -Wl upon setting LINK_FLAGS, i.e.:
set_target_properties(
proj PROPERTIES LINK_FLAGS "-Wl,-T${proj_SOURCE_DIR}/link.ld,-melf_i386")