#Why is CMake not linking my headers?

25 messages · Page 1 of 1 (latest)

dapper knollBOT
#

When your question is answered use !solved or the button below to mark the question as resolved.

Remember to ask specific questions, provide necessary details, and reduce your question to its simplest form. For tips on how to ask a good question use !howto ask.

mortal plover
#
  1. you probably shouldn't be compiling headers separately. You include those in source files, for the code in them to then be compiled
  2. what does memory_pool.c look like? Does it provide definitions for sexpr_MemoryNode and so on? Your header only provides declarations
#

Typically when you want to do this #include style generics, you put all the definitions in the header as well, locked behind a MEMORY_POOL_IMPL define. That way in one use you can do define MEMORY_POOL_IMPL before including and then all the others just use the declarations

#

Yeah so this will only make definitions for int_MemoryNode and so on

#

Well even if you remove it, it doesn't matter

#

This is a separate translation unit. It can not see the defines of other translation unit

mortal plover
#
#ifdef MEMORY_POOL_TYPE
#ifdef MEMORY_POOL_PREFIX

#ifdef MEMORY_POOL_GARBAGE_COLLECTION
#include <stdbool.h>
#endif // MEMORY_POOL_GARBAGE_COLLECTION

struct MEMORY_POOL_PREFIX(MemoryNode) {
  MEMORY_POOL_TYPE data;
  struct MEMORY_POOL_PREFIX(MemoryNode) *next;
#ifdef MEMORY_POOL_GARBAGE_COLLECTION
  bool mark;
#endif // MEMORY_POOL_GARBAGE_COLLECTION
};

typedef struct MEMORY_POOL_PREFIX(MemoryNode) \
  MEMORY_POOL_PREFIX(MemoryNode);

MEMORY_POOL_PREFIX(MemoryNode) MEMORY_POOL_PREFIX(memory_node_new)();



struct MEMORY_POOL_PREFIX(MemoryPool) {
  MEMORY_POOL_PREFIX(MemoryNode) *array;
  size_t capacity;
  MEMORY_POOL_PREFIX(MemoryNode) *free;
  struct MEMORY_POOL_PREFIX(MemoryPool) *next;
};

typedef struct MEMORY_POOL_PREFIX(MemoryPool) \
  MEMORY_POOL_PREFIX(MemoryPool);

MEMORY_POOL_PREFIX(MemoryPool) *MEMORY_POOL_PREFIX(memory_pool_new)(size_t capacity);

void MEMORY_POOL_PREFIX(memory_pool_free)(MEMORY_POOL_PREFIX(MemoryPool) *pool);

MEMORY_POOL_TYPE *MEMORY_POOL_PREFIX(memory_alloc)(MEMORY_POOL_PREFIX(MemoryPool) *pool);

void MEMORY_POOL_PREFIX(memory_free)(MEMORY_POOL_PREFIX(MemoryPool) *pool, MEMORY_POOL_TYPE *ptr);

#ifdef MEMORY_POOL_IMPL

void MEMORY_POOL_PREFIX(memory_pool_free)(MEMORY_POOL_PREFIX(MemoryPool) *pool) {
  if (pool->next != NULL) {
    free(pool->next);
  }

  free(pool->array);
  free(pool);
}

#endif

#endif // MEMORY_POOL_PREFIX
#endif // MEMORY_POOL_TYPE
#

Just with free as an example

#

When the user does #define MEMORY_POOL_IMPL before including, then it will also include all of the definition code. The user has to take care to only do this once

#

No, you're only providing declarations currently

#

Declaration != definition

#

You can define it to whatever you want, since the header only checks if it's defined or not

#

If you didn't do #define MEMORY_POOL_IMPL before including, then it's not defined and the implementations won't be included

#

Yes

#

The problem comes from the fact that your original memory_pool.h only provides declarations, which just tell C that these functions/objects exist somewhere somehow with the types you said they have. You need definitions for there to be actual code to run or an actual value to access

#

So you provide another flag MEMORY_POOL_IMPL that, when defined, will also provide these definitions

#

Yes. You would basically copy paste all the definitions you wrote in memory_pool.c into memory_pool.h like so

#ifdef MEMORY_POOL_IMPL
<code here>
#endif```
#

It doesn't. You put it all in the header

#

See any "header only" library as an example

#

Everything is in the header

dapper knollBOT
#

@thorn finch Has your question been resolved? If so, type !solved :)

mortal plover
#

Hopefully this makes it more clear what's going on with your original code```c
// TU 1
int int_Meow() { return 292; }

// TU 2
int int_Meow(); // tell compiler a function named int_Meow that returns int is defined somewhere else.
int_Meow(); // linker finds a definition in TU 1! Yields 292

float float_Meow(); // tell compiler a function named float_Meow that returns float is defined somewhere else.
float_Meow(); // linker finds no definition anywhere. Error!

#

You avoid the multiple redefinition with the MEMORY_POOL_IMPL define. If MEMORY_POOL_IMPL is not defined you only get declarations

dapper knollBOT
#

Thank you and let us know if you have any more questions!

This thread is now set to auto-hide after an hour of inactivity