Re: [CMake] C header file cross dependency

2016-07-05 Thread Wagner Martin
Hi @all,

I've finally found a solution to the problem.

My solution is here: https://github.com/martinwag/test_cmake/tree/master

What I did:
- remove  "OBJECT" library targets as they do not work in combination with 
interface libraries
- added one install target per library, so I get one "lib*.a" archive per 
library (which is not what I need)
- added an post install target as described here: 
stackoverflow.com/questions/9998679 . This step creates a "thin" archive, that 
is packed with the other archives at cpack-time. This archive can be used as 
single file when linking in the consuming stage.

Regards,
Martin
 
 

-- 

Powered by www.kitware.com

Please keep messages on-topic and check the CMake FAQ at: 
http://www.cmake.org/Wiki/CMake_FAQ

Kitware offers various services to support the CMake community. For more 
information on each offering, please visit:

CMake Support: http://cmake.org/cmake/help/support.html
CMake Consulting: http://cmake.org/cmake/help/consulting.html
CMake Training Courses: http://cmake.org/cmake/help/training.html

Visit other Kitware open-source projects at 
http://www.kitware.com/opensource/opensource.html

Follow this link to subscribe/unsubscribe:
http://public.kitware.com/mailman/listinfo/cmake


Re: [CMake] C header file cross dependency

2016-06-23 Thread Wagner Martin
Hi Patrick,

thank you for your answer and sorry that it took me a while to work on it.

> 
> I forked your repo and played a little bit around.
> 
> https://github.com/pboettch/test_cmake

I pulled those changes and played aroud a bit myself.

https://github.com/martinwag/test_cmake

I'm now back at the point where I decided to use cmake's OBJECTS functionality. 
I didn't find any other way to pack all compiled products into an 
easy-to-include-and-link package for the application.

I was unable to use target_link_libraries() because this actually wants to do 
linking instead of just packaging. The way you used it

add_library(bsp INTERFACE)
target_link_libraries(bsp INTERFACE drivers terminal)
install(TARGETS bsp DESTINATION ${ARCHIVE_INSTALL_DIR})

the install command runs, but does not install anything, resulting in an 
archive with just the headers.


I'm open to package the archive in a different way - install(EXPORT ...) seems 
promising. The important thing to me is that the consuming application doesn't 
need inside knowledge of the bsp package.


> 
> Here are my conclusions:
> 
> 1) Due to the use of add_libary(... OBJECTS ...) you cannot link
> libraries with libraries or interfaces, this is a pity - especially for
> a complex project with a lot of sub-dirs.
> 
> There is a possibility to merge STATIC-libraries to generated one big
> archive using external tools (libtool). If I were you I'd try to this
> way to profit from the target_*-cmake-features.

See above.

> 
> 2) I created a log-dir with an interface-library - which only carries
> the log.h and thus the printf-prototypes
> 
> 3) Both, drivers and terminal link with this interface-library (to get
> their hands on log.h)
> 

This sounds good - I have to check if that works in the (more complex) 
production code.

> 4) In addition I added two libraries to drivers/ uart-logging1 and uart-
> logging2. This shows how you could compile-configure your printf-
> function depending on the hardware used. In the main CMakeLists you just
> need to select one of them - depending on the option's value.
> 
> Basically I followed the idea of instantiating a print-function
> 'somewhere' in the project (it could also be done outside) and then
> select the one you want to use at the final link.
> 
> Of course this way you could add other ways of printf'ing - logging1 and
> logging2 are just stupid examples.

This is -more or less- already in my production code. I want to do all this 
stuff in one configuration header file inside the application.
However, I think it's a good idea to have the option to replace the printing 
function with "anything".

I removed that part to keep the example as simple as possible.


> 
> HTH and sorry for the delay,
Obviously I'm not the fastest myself :-).

Regards,
Martin
-- 

Powered by www.kitware.com

Please keep messages on-topic and check the CMake FAQ at: 
http://www.cmake.org/Wiki/CMake_FAQ

Kitware offers various services to support the CMake community. For more 
information on each offering, please visit:

CMake Support: http://cmake.org/cmake/help/support.html
CMake Consulting: http://cmake.org/cmake/help/consulting.html
CMake Training Courses: http://cmake.org/cmake/help/training.html

Visit other Kitware open-source projects at 
http://www.kitware.com/opensource/opensource.html

Follow this link to subscribe/unsubscribe:
http://public.kitware.com/mailman/listinfo/cmake


Re: [CMake] C header file cross dependency

2016-06-06 Thread Patrick Boettcher
Hi Martin,

On Wed, 1 Jun 2016 14:58:53 +
Wagner Martin  wrote:

> > 
> > Could you provide a working, stripped down example to show the
> > problem provided via github (in an example repo).
> >   
> 
> I've added a simple test project to 
> 
> https://github.com/martinwag/test_cmake/tree/master
> 
> Note that this example does not need cross gcc for ARM. It doesn't
> implement any useful functionality!

I forked your repo and played a little bit around. 

https://github.com/pboettch/test_cmake

Here are my conclusions:

1) Due to the use of add_libary(... OBJECTS ...) you cannot link
libraries with libraries or interfaces, this is a pity - especially for
a complex project with a lot of sub-dirs. 

There is a possibility to merge STATIC-libraries to generated one big
archive using external tools (libtool). If I were you I'd try to
this way to profit from the target_*-cmake-features.

2) I created a log-dir with an interface-library - which only carries
the log.h and thus the printf-prototypes

3) Both, drivers and terminal link with this interface-library (to get
their hands on log.h)

4) In addition I added two libraries to drivers/ uart-logging1 and
uart-logging2. This shows how you could compile-configure your
printf-function depending on the hardware used. In the main CMakeLists
you just need to select one of them - depending on the option's value.

Basically I followed the idea of instantiating a print-function
'somewhere' in the project (it could also be done outside) and then
select the one you want to use at the final link.

Of course this way you could add other ways of printf'ing - logging1
and logging2 are just stupid examples.

HTH and sorry for the delay,
--
Patrick.



-- 

Powered by www.kitware.com

Please keep messages on-topic and check the CMake FAQ at: 
http://www.cmake.org/Wiki/CMake_FAQ

Kitware offers various services to support the CMake community. For more 
information on each offering, please visit:

CMake Support: http://cmake.org/cmake/help/support.html
CMake Consulting: http://cmake.org/cmake/help/consulting.html
CMake Training Courses: http://cmake.org/cmake/help/training.html

Visit other Kitware open-source projects at 
http://www.kitware.com/opensource/opensource.html

Follow this link to subscribe/unsubscribe:
http://public.kitware.com/mailman/listinfo/cmake


Re: [CMake] C header file cross dependency

2016-06-01 Thread Wagner Martin
> 
> Could you provide a working, stripped down example to show the problem
> provided via github (in an example repo).
> 

I've added a simple test project to 

https://github.com/martinwag/test_cmake/tree/master

Note that this example does not need cross gcc for ARM. It doesn't implement 
any useful functionality!

Regards,
Martin
-- 

Powered by www.kitware.com

Please keep messages on-topic and check the CMake FAQ at: 
http://www.cmake.org/Wiki/CMake_FAQ

Kitware offers various services to support the CMake community. For more 
information on each offering, please visit:

CMake Support: http://cmake.org/cmake/help/support.html
CMake Consulting: http://cmake.org/cmake/help/consulting.html
CMake Training Courses: http://cmake.org/cmake/help/training.html

Visit other Kitware open-source projects at 
http://www.kitware.com/opensource/opensource.html

Follow this link to subscribe/unsubscribe:
http://public.kitware.com/mailman/listinfo/cmake


Re: [CMake] C header file cross dependency

2016-05-31 Thread Wagner Martin
Thank you for your answer!

> > How do I resolve something like this? Right now CMake evaluates the
> > compiler includes in the order that subdirectories are added. This
> > gives me an compilation error in uart.c that terminal.h cannot be
> > found.
> 
> This is not a cmake-problem, but seems to be a code-structure-issue.
> 
> I'm guessing here: if terminal needs the uart-code shouldn't it be the
> uart-code filling in a terminal-function. Interface vs. implementation?
> Could you elaborate more on how terminal and uart are linked?

The terminal code implements a "printf()" equivalent function to log debug and 
state information. All input is then directly written to the UART.

The UART driver now wants to use this terminal logging function. It doesn't 
care how printf() works. 

In the end, this is necessary because there is no file system to store the log 
information to. I would like to have this:
uart_write(uart2) -> syslog(prio, errormsg) -> syslog.txt on file system.
But I have:
uart_write(uart2) -> printf(errormsg) -> uart_write(uart1) -> PC with running 
terminal software

> 
> Regarding cmake: I suggest you stop using include_directories() and
> start using target_include_directories() and
> target_compile_definitions() instead of add_definitions().

I will have a look at this.

> 
> Limiting yourself to this way of doing libraries and targets, cmake will
> force you to structure your code in a more standard way - and will
> provide you with clean visibility between different targets.
> 
> Could you provide a working, stripped down example to show the problem
> provided via github (in an example repo).

I will try to do this within a few days...

> 
> More comments below.
> 
> > Some excerpt of my project. I've tried to keep the example as simple
> > as possible.
> >
> > My directory structure looks something like that:
> > /
> > CMakeLists.txt
> > src +
> > +CMakeLists.txt(1)
> > +drivers+
> > |   +uart.c
> > |   +uart.h
> > |   +...
> > |   +CMakeLists.txt(2)
> > +os-+
> > |   +terminal.c
> > |   +terminal.h
> > |   +...
> > |   +CMakeLists.txt(3)
> >
> >
> > (1):
> >
> > SET(drivers "drivers")
> > SET(terminal "terminal")
> >
> > SET(drivers_lib ${drivers})
> > SET(terminal_lib ${terminal})
> >
> > SET(ARCHIVE_INSTALL_DIR lib)
> > SET(INCLUDE_INSTALL_DIR include)
> >
> > SET(headers_private "_headers_private") # internal headers
> > SET(headers_public "_headers_public")   # public headers go into
> > package
> >
> > ADD_SUBDIRECTORY(${drivers})
> > ADD_SUBDIRECTORY(${terminal})
> 
> I think it is common practice now to use lower-case for cmake-commands
> now.

OK.

> 
> > ## drivers
> >
> > ##  Sources
> > ---
> > SET(sources "uart.c"
> > )
> >
> > ##  Header includes
> > ---
> > SET(headers "${CMAKE_CURRENT_SOURCE_DIR}/"
> > )
> > SET(${drivers}${headers_public} ${headers} PARENT_SCOPE)
> >
> > INCLUDE_DIRECTORIES(${headers}
> > ${${terminal}${headers_public}}
> > )
> 
> While the ${${var}${var2}} (seems to) work, it is error-prone, IMHO.
> 
> Standard cmake-commands can work with relative paths and are evaluating
> them correctly taking into account ${CMAKE_CURRENT_SOURCE_DIR} (most of
> the time. So you could use ../uart in terminal/ 

This is what I did to continue working...

> - but it would be better
> if it comes indirectly via target_include_directories() and
> target_link_libraries()

...and this is why I asked the list :-)

> 
> >[..]
> >
> > And finally this creates the package in root directory CMakeLists.txt:
> >
> > SET(CPACK_PROJECT_CONFIG_FILE ${CMAKE_BINARY_DIR}/CPackOptions.cmake)
> > # CPackOptions.cmake contains package file name SET(CPACK_GENERATOR
> > "TBZ2") INCLUDE(CPack)
> 
> Due to the circular header-dependency the binaries of terminal and uart
> should have the same mutual dependency. In this case you could build
> them in within one target.

Yes, I could do that. But I wanted to get away from one single, monolithic 
makefile...
This is why I created one CMake file for every functional unit of my source 
code (drivers, RTOS, terminal and so on).

regards,
Martin

-- 

Powered by www.kitware.com

Please keep messages on-topic and check the CMake FAQ at: 
http://www.cmake.org/Wiki/CMake_FAQ

Kitware offers various services to support the CMake community. For more 
information on each offering, please visit:

CMake Support: http://cmake.org/cmake/help/support.html
CMake Consulting: http://cmake.org/cmake/help/consulting.html
CMake Training Courses: http://cmake.org/cmake/help/training.html

Visit other Kitware open-source projects at 
http://www.kitware.com/opensource/opensource.html

Follow this link to subscribe/unsubscribe:
http://public.kitware.com/mailman/listinfo/cmake


Re: [CMake] C header file cross dependency

2016-05-25 Thread Patrick Boettcher
On Mon, 23 May 2016 13:49:14 +
Wagner Martin  wrote:

> Hi @all,
> 
> I'm quite new to CMake. If I've made a mistake or something is much
> easier to solve, please tell me.
> 
> I'd like to use CMake in embedded development (Build System: Linux,
> Target: ARM Microcontroller) to get rid of complicated makefiles.

Good thing! 

> We're building multiple devices where stuff like embedded rtos and
> peripheral drivers are identical, so I'd like to separate this part
> from the user application. I've achieved that by creating an object
> library out of all source and header files, and packing those files
> using CPack. This archive is then statically linked against the user
> application.
> 
> So far this worked fine. However, now I have to use driver functions
> in the rtos source code and vice versa, resulting in
> cross-dependencies for header files:
> 
> 
> 
> #include uart.h
> #include terminal.h
> 
> function() {}
> 
> 
> 
> #include terminal.h
> #include uart.h
> 
> function() {}
> 
> How do I resolve something like this? Right now CMake evaluates the
> compiler includes in the order that subdirectories are added. This
> gives me an compilation error in uart.c that terminal.h cannot be
> found.

This is not a cmake-problem, but seems to be a code-structure-issue.

I'm guessing here: if terminal needs the uart-code shouldn't it be the
uart-code filling in a terminal-function. Interface vs. implementation?
Could you elaborate more on how terminal and uart are linked?

Regarding cmake: I suggest you stop using include_directories() and
start using target_include_directories() and
target_compile_definitions() instead of add_definitions().

Limiting yourself to this way of doing libraries and targets, cmake will
force you to structure your code in a more standard way - and will
provide you with clean visibility between different targets.

Could you provide a working, stripped down example to show the problem
provided via github (in an example repo).

More comments below.
 
> Some excerpt of my project. I've tried to keep the example as simple
> as possible.
> 
> My directory structure looks something like that:
> /
> CMakeLists.txt
> src +
> +CMakeLists.txt(1)
> +drivers+
> |   +uart.c
> |   +uart.h
> |   +...
> |   +CMakeLists.txt(2)
> +os-+
> |   +terminal.c
> |   +terminal.h
> |   +...
> |   +CMakeLists.txt(3)
> 
> 
> (1):
> 
> SET(drivers "drivers")
> SET(terminal "terminal")
> 
> SET(drivers_lib ${drivers})
> SET(terminal_lib ${terminal})
> 
> SET(ARCHIVE_INSTALL_DIR lib)
> SET(INCLUDE_INSTALL_DIR include)
> 
> SET(headers_private "_headers_private") # internal headers
> SET(headers_public "_headers_public")   # public headers go into
> package
> 
> ADD_SUBDIRECTORY(${drivers})
> ADD_SUBDIRECTORY(${terminal})

I think it is common practice now to use lower-case for cmake-commands
now. 

> ## drivers
> 
> ##  Sources
> ---
> SET(sources "uart.c"
> )
> 
> ##  Header includes
> ---
> SET(headers "${CMAKE_CURRENT_SOURCE_DIR}/" 
> )
> SET(${drivers}${headers_public} ${headers} PARENT_SCOPE)
> 
> INCLUDE_DIRECTORIES(${headers} 
> ${${terminal}${headers_public}}
> )

While the ${${var}${var2}} (seems to) work, it is error-prone, IMHO.

Standard cmake-commands can work with relative paths and are evaluating
them correctly taking into account ${CMAKE_CURRENT_SOURCE_DIR} (most of
the time. So you could use ../uart in terminal/ - but it would be
better if it comes indirectly via target_include_directories() and
target_link_libraries()

>[..]
> 
> And finally this creates the package in root directory CMakeLists.txt:
> 
> SET(CPACK_PROJECT_CONFIG_FILE ${CMAKE_BINARY_DIR}/CPackOptions.cmake)
> # CPackOptions.cmake contains package file name SET(CPACK_GENERATOR
> "TBZ2") INCLUDE(CPack)

Due to the circular header-dependency the binaries of terminal and uart
should have the same mutual dependency. In this case you could build
them in within one target.

regards
--
Patrick.

-- 

Powered by www.kitware.com

Please keep messages on-topic and check the CMake FAQ at: 
http://www.cmake.org/Wiki/CMake_FAQ

Kitware offers various services to support the CMake community. For more 
information on each offering, please visit:

CMake Support: http://cmake.org/cmake/help/support.html
CMake Consulting: http://cmake.org/cmake/help/consulting.html
CMake Training Courses: http://cmake.org/cmake/help/training.html

Visit other Kitware open-source projects at 
http://www.kitware.com/opensource/opensource.html

Follow this link to subscribe/unsubscribe:
http://public.kitware.com/mailman/listinfo/cmake