6

I'm trying to write a bare-metal program with CMake(my project is locate in https://github.com/oska874/cmake_test). The demo source code are these:

my.c

void mymain(void)
{
    int a=0;
    a++;
    a++;
}

and link script file is :

my.lds

ENTRY(mymain)
SECTIONS
{   
   . = 0x10000;
   .text : { *(.text) }
   . = 0x8000000;
   .data : { *(.data) }
   .bss : { *(.bss) }
}

I can compile it with command bellow:

gcc -c my.c
ld -T my.lds -o my my.o

But I don't know how to do the same thing with CMake for cmake always use its' own .lds script.

I tried search google and stackoverflow but all method failed.

/usr/lib/gcc/x86_64-linux-gnu/5/../../../x86_64-linux-gnu/crt1.o: In function `_start':
(.text+0x20): undefined reference to `main'

I have tried CMakeLists.txt as bellow:

PROJECT(FreeRtos)
CMAKE_MINIMUM_REQUIRED(VERSION 2.8)

set(CMAKE_EXE_LINKER_FLAGS_DEBUG " -T ${CMAKE_SOURCE_DIR}/my.lds -static")

AUX_SOURCE_DIRECTORY(. MYSRC)
ADD_EXECUTABLE(my  ${MYSRC} )

set(CMAKE_BUILD_TYPE Debug CACHE STRING "Choose the type of build." FORCE)

And this

CMAKE_MINIMUM_REQUIRED(VERSION 2.8 FATAL_ERROR)
PROJECT(LINKERSCRIPT C)
# dummy.c must exist:
ADD_EXECUTABLE(EXE my.c dummy.c)
# linkerscript must exist:
SET_SOURCE_FILES_PROPERTIES(
        dummy.c PROPERTIES OBJECT_DEPENDS ${CMAKE_SOURCE_DIR}/my.lds
        )

I checked the link.txt in CMakeFiles/EXE.dir/ ,it shows that :

 /usr/bin/cc  -g     -T /os_dev/workspace/test/ezio/tool/eo/freertos-pine64/Source/t2/my.lds -static CMakeFiles/my.dir/my.c.o  -o my -rdynamic

I tried to exchange cc with ld with command that:

SET(CMAKE_C_LINK_EXECUTABLE "/usr/bin/ld <CMAKE_C_LINK_FLAGS> <LINK_FLAGS> <OBJECTS>  -o <TARGET>")

It works ,the link.txt shows CMake will use my.lds.

Ezio
  • 1,116
  • 4
  • 13
  • 25
  • Just pass `-T my.lds` as **linker flags**, as described here: http://stackoverflow.com/questions/6077414/cmake-how-to-set-the-ldflags-in-cmakelists-txt. – Tsyvarev Mar 23 '17 at 14:24
  • @Tsyvarev Alreday tried but has no effect. – Ezio Mar 23 '17 at 14:28
  • Then show the code (`CMakeLists.txt`) which have you tried. – Tsyvarev Mar 23 '17 at 14:29
  • @Tsyvarev I've post one. – Ezio Mar 23 '17 at 14:33
  • **The first approach**: Variable CMAKE_EXE_LINKER_FLAGS_DEBUG is used only when build type is "Debug". You attempt to set defaul type, but do that *incorrectly* (you should set *cached* variable). See [that answer](http://stackoverflow.com/a/40482191/3440745) about proper way for set default build type. If you don't wont to bother with build type, just append flags to *CMAKE_EXE_LINKER_FLAGS* variable: it is always used. **The second approach** just adds dependency from the given file, it doesn't treat this file as a linker script automatically. – Tsyvarev Mar 23 '17 at 18:55
  • @Tsyvarev Thank you. After modify `CMAKE_BUILD_TYPE ` with your comment,link.txt can find the link script,but still have some question as showed ,1. CMake use cc instead of ld to linking, 2. how to remove the `-rdynamic` option ? – Ezio Mar 24 '17 at 05:43
  • As I see, you have already find the [proper way](http://stackoverflow.com/a/25274328/3440745) for specifying the linker. As for removing `-rdynamic` option, it is easily googled: http://public.kitware.com/pipermail/cmake/2009-October/032948.html. (Because you create executable, you need to modify *CMAKE_EXE_LINKER_FLAGS* variable). – Tsyvarev Mar 24 '17 at 07:57

1 Answers1

4

CMake has no special variable for ldscript, so you may resort to appending appropriate linker flags:

set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -T ${CMAKE_SOURCE_DIR}/my.lds")

(This should be placed after project() call in CMakeLists.txt).

See that question for more information about setting linker flags in CMake.

Community
  • 1
  • 1
Tsyvarev
  • 60,011
  • 17
  • 110
  • 153