В этой истории самое печальное то, что это все — только начало. Слишком это ценная штука, держать под колпаком миллиарды юзеров и быть властителем их мыслей. Соблазн так велик, что никто от этого не откажется. Человечество мечтало об этом всю свою историю.
Если же кто-то считает, что их спасет Линукс или опенсорс, то он просто продержится чуть дольше. Поэтому, как говорится, здравствуй, прекрасный новый мир. Очень хотелось бы ошибаться.
Ничто не мешает использовать наш подход и с С++, только он (наш инструмент), конечно, не будет ничего знать о классах, тут нужны какие-то соглашения, например имя модуля = имя класса, и один класс — один файл, как в java.
Концепты тоже крайне интересная тема, для меня, по крайней мере. В планах на будущее — сделать проверку соответствия хидера и «интерфейса», то есть интерфейс должен быть описан каким-то IDL-ом, который для сборки исходников не нужен и может в ней не участвовать, но, когда кто-то написал реализацию модуля, чтоб он мог проверить, что его модуль точно соответствует интерфейсу, который он собрался из него экспортировать.
Сложность в том, что самый простой случай, вроде совпадения имен функций и структур данных не дает гарантий, что модуль «подойдет», тут нужен концепт и какое-то его описание + возможность автоматической проверки соответствия кода концепту.
Все, нашел про хидеры :-) Надо было по ссылкам дальше пройти. Ну, это одно из решений «виртуального хидера», с помощью внешних средств (файловой системы). Зависимости, тем не менее, между модулями не отслеживаются автоматически и закомменчивание инклуда, который тянет за собой кучу всего, не влечет исключение этой «кучи всего» из билда.
Я может невнимательно прочитал, но там речь о подключении библиотек в зависимости от процессоров. Где там меняется header я не нашел. По поводу зависимостей я тоже не понял, как можно отследить зависимость исходников от хидеров (помимо этих зависимостей есть еще зависимости модулей от модулей, а не только хидеров от исходников)?
Про то, что переменные в исходниках, речь о том и идет, что надо содержать в исходниках то, что по смыслу в исходниках, иначе надо согласовывать исходники и метаданные вручную.
Про то, что негибко где-то, согласен, у нас при разработке ОС была такая проблема, что некоторые файлы, вроде тех, которые содержат таблицы прерываний по определенным адресам, явно никем не используются, но должны быть включены в билд принудительно. Мы решаем эту проблему тем, что обычно собирается некоторое «ядро», которое «корневой модуль» и в нем перечисляется то, что должно входить в сборку, и вот туда включаются модули (инклудами), которые должны быть включены принудительно. Ну или можно задавать какой-то список «принудительных модулей» самому скрипту, но это криво как-то и выглядит костылем, поэтому пока все только на дереве зависимостей.
Это во-первых не на уровне исходников, а на уровне библиотек, а во-вторых тут опять же речь о конфигурировании в заданных рамках и без отслеживания зависимостей.
Ну почему, и для этого тоже нужна, многие вещи имеют «аспектную» природу: логирование, дебаг, поддержка многопроцессорности, безопасность и т.д. и т.п… Модули нужны много для чего, понятно, что каждую конкретную задачу в конкретном проекте можно и без них решить. Просто речь о том, что можно в исходниках хранить ту информацию которая там уже есть по смыслу, и это упрощает жизнь. Если более удобно поддерживать согласованность исходников и билда вручную или с помощью каких-то соглашений, то никто с этим не спорит. Если вдруг заккоментируешь какой-то инклуд, и модуль становится не нужен, надо вручную подкрутить систему сборки, установить какие-то переменные и т.д., а тут говорится о том, что можно просто закомментить инклуд и все.
По факту, информации о связях между заголовочными файлами и исходниками нет нигде. Даже распарсив исходники ее не установишь, т.к. может быть несколько реализаций в разных файлах. Если эту информацию зарыть в исходники — все сведется к тому что тут, либо к тому что в Pascal. Если информации в исходниках нет, значит она будет лежать снаружи в виде метаданных для системы сборки, и поддерживать согласованность исходников и метаданных надо будет вручную. Вот в этом поинт.
Нет, пост не совсем об этом. Точнее, совсем не об этом. Он он том, что можно написать #include INTERFACE(CPU, DEFAULT) и не задумываться ни об именах файлов, ни об путях для include. В большинстве случаев, в конечном итоге все выльется во второй вариант, но можно написать такой заголовочный файл, чтоб там был макрос #define func(). Если назначить его как дефолтный интерфейс, тогда все вызовы функций func исчезнут из всех исходников, которые включают INTERFACE(CPU, DEFAULT), то есть конфигурирование не на уровне подлинковки нужной либы, содержащей реализацию нужной функции, а на уровне исходников.
Я как-раз написал о разнице, между закрытой и открытой системой конфигурирования. Когда есть набор _заранее_определенных_ переменных, которые включают или отключают что-то, это не совсем то. Например, как можно подменить реализацию какого-то модуля добавив новый модуль (на уровне исходников)? Нужно, во-первых, прописать его в файлы CMake, зависимости «его» и «от него» и имена его собственных файлов. Если повезет, и структура каталогов подобрана удачно, тогда, перенастройкой default include dir, вероятно, можно добиться того, чтоб старые компоненты проинклудили его, иначе придется менять исходники старых компонентов.
Дело не в организации структуры папок, а в том, чтоб инклуд был абстрактным. В Вашем примере инклуд все равно подключает какой-то конкретный компонент, заменить его на другой, без изменения исходников нельзя.
Когда все начиналось, никакой структуры папок не было вовсе, нужно было решать вопрос о комбинировании модулей на уровне исходников с сохранением интерфейсов и без поддержки какой-либо согласованности между исходниками и системой билда вручную. А потом уже все писалось изначально так, как описано.
В свою очередь, мне любопытно, как можно сделать «унифицированное подключение компонентов к проекту» без всего этого.
Может быть я неправильно понял вопрос, но исходники могут быть расположены как угодно, скрипту дается «папка проекта» в которой лежат вообще все исходники, а он сам должен в них найти все интерфейсы и реализации. Как исходники раскладываются по папкам — дело вкуса разработчика. Можно менять структуру исходников и имена файлов произвольным образом.
Спасибо! Embox я видел, но, правда, очень давно, надо как-то посмотреть новые версии :-)
У нас все ориентировано в данный момент на более deep, так сказать, embedded, уровня cortex m0/m3 без MMU. Как FreeRTOS.
Может быть, смотря какой диэлектрик, SiO2 вполне переживёт. Естессно что чип приходит в негодность после такого, но я бы не сказал, что его структура портится, по крайней мере все эти дорожки, соединения и прочее было видно. Ну и вообще там много интересного, на чипе есть неиспользованное место по углам, там бывают всякие надписи, на AMD-шном сопроцессоре 287 было даже что-то типа изображения меча с какими-то номерами вокруг.
Я в детстве таким развлекался (изучением чипов под микроскопом). Не знаю, почему профессор сам не догадался, но есть гораздо менее варварский способ извлечь чип из упаковки. Касается он в первую очередь обычных микросхем (в обычном DIP-корпусе).
Метод прост и изящен, т.к. сам чип выдерживает высокие температуры (это часть техпроцесса при производстве), то можно просто бросить микросхему в костёр. После минут 5-10 в огне, черный корпус станет белым и очень хрупким. Достаем из костра, ждём, пока остынет, после чего пальцами разламываем корпус пополам и нам в ладонь падает аккуратный прямоугольный кристалл без сколов и царапин, готовый к изучению под микроскопом.
Я специально говорю здесь про костёр, а не про газовую плиту на кухне, потому что во втором случае будет много вони от горящего пластика и, возможно, этим очень вредно дышать. Так что только костёр на открытом воздухе.
Либо я чего-то не понял, либо Вы тоже заблуждаетесь. Та память, которую «не видно» — это memory mapped I/O и области для доступа к видеокарте например, к ее памяти через адресное пространство оперативной. Так или иначе, эти адреса недоступны физически на уровне PCI-мостов, никакими ухищрениями с пейджингом увидеть их не получится. Это тот случай, когда памяти ровно 4 гига. Если памяти больше, скажем 8 гигов, тогда можно написать свой драйвер RAM-disk-а, который сможет использовать память выше 4 гигов (то что между 3,3 и 4 увидеть все-равно не получится) но смысла в этом никакого, тут надо ставить x64.
У современных чипсетов есть такая фича — memory remap feature, которая позволяет отмапить часть оперативки в пространство выше 4Gb, на первый взгляд кажется, что это то что нужно, пишем свой драйвер, работающий с этой памятью и размещаем своп там, выше 4 гигов. На практике это опять же лишено всякого смысла, потому что для доступа к этой памяти нужен диапазон адресов в первых 4-х гигах, которые придется попросить из системного адресного пространства и вручную поправить таблицы страниц, но мы при этом забираем у системы виртуальные адреса, которые ей возможно нужнее, чем дополнительный своп, можно конечно каждый раз выделять/освобождать при каждом обращении к этому «свопу», но в этом еще меньше смысла.
В общем я бы сказал так, теоретически при наличии должной поддержки со стороны желаза и в каком-то особом случае, когда известно что можно безболезненно забрать у системы часть системного виртуального адресного пространства, это может и принесет какую-то пользу, но всем и каждому я бы это не рекомендовал. Это примерно как кошке пятая нога иногда может быть полезна. Поправьте меня.
Я не знаю как все будет, но может быть например так: в целях заботы о безопасности пользователей, защиты от хакеров и руткитов, борьбы с фрагментацией платформы и тэдэ и тэпэ, делаем неотключаемый secure boot. После этого остаются 2-3 вендора типа RedHat и Ubuntu с которыми можно провести разъяснительную работу. А 2% (оптимистично) тех, кто собирает ядра сам, никто слушать не будет.
Он уже сейчас кое где сделан неотключаемым, но пока еще можно перешить BIOS самому. Но не забываем, что взят курс на то, чтоб сделать процессоры SoC-ами, и в конечном итоге все упрётся в производство микросхем, после того, как защита от «неправильного» софта будет зашита прямо туда. А Fab-ов, стоящих миллиарды, в распоряжении хиппи-идеалистов не было и никогда не будет.
Если же кто-то считает, что их спасет Линукс или опенсорс, то он просто продержится чуть дольше. Поэтому, как говорится, здравствуй, прекрасный новый мир. Очень хотелось бы ошибаться.
Концепты тоже крайне интересная тема, для меня, по крайней мере. В планах на будущее — сделать проверку соответствия хидера и «интерфейса», то есть интерфейс должен быть описан каким-то IDL-ом, который для сборки исходников не нужен и может в ней не участвовать, но, когда кто-то написал реализацию модуля, чтоб он мог проверить, что его модуль точно соответствует интерфейсу, который он собрался из него экспортировать.
Сложность в том, что самый простой случай, вроде совпадения имен функций и структур данных не дает гарантий, что модуль «подойдет», тут нужен концепт и какое-то его описание + возможность автоматической проверки соответствия кода концепту.
Про то, что переменные в исходниках, речь о том и идет, что надо содержать в исходниках то, что по смыслу в исходниках, иначе надо согласовывать исходники и метаданные вручную.
Про то, что негибко где-то, согласен, у нас при разработке ОС была такая проблема, что некоторые файлы, вроде тех, которые содержат таблицы прерываний по определенным адресам, явно никем не используются, но должны быть включены в билд принудительно. Мы решаем эту проблему тем, что обычно собирается некоторое «ядро», которое «корневой модуль» и в нем перечисляется то, что должно входить в сборку, и вот туда включаются модули (инклудами), которые должны быть включены принудительно. Ну или можно задавать какой-то список «принудительных модулей» самому скрипту, но это криво как-то и выглядит костылем, поэтому пока все только на дереве зависимостей.
По факту, информации о связях между заголовочными файлами и исходниками нет нигде. Даже распарсив исходники ее не установишь, т.к. может быть несколько реализаций в разных файлах. Если эту информацию зарыть в исходники — все сведется к тому что тут, либо к тому что в Pascal. Если информации в исходниках нет, значит она будет лежать снаружи в виде метаданных для системы сборки, и поддерживать согласованность исходников и метаданных надо будет вручную. Вот в этом поинт.
В свою очередь, мне любопытно, как можно сделать «унифицированное подключение компонентов к проекту» без всего этого.
У нас все ориентировано в данный момент на более deep, так сказать, embedded, уровня cortex m0/m3 без MMU. Как FreeRTOS.
Метод прост и изящен, т.к. сам чип выдерживает высокие температуры (это часть техпроцесса при производстве), то можно просто бросить микросхему в костёр. После минут 5-10 в огне, черный корпус станет белым и очень хрупким. Достаем из костра, ждём, пока остынет, после чего пальцами разламываем корпус пополам и нам в ладонь падает аккуратный прямоугольный кристалл без сколов и царапин, готовый к изучению под микроскопом.
Я специально говорю здесь про костёр, а не про газовую плиту на кухне, потому что во втором случае будет много вони от горящего пластика и, возможно, этим очень вредно дышать. Так что только костёр на открытом воздухе.
У современных чипсетов есть такая фича — memory remap feature, которая позволяет отмапить часть оперативки в пространство выше 4Gb, на первый взгляд кажется, что это то что нужно, пишем свой драйвер, работающий с этой памятью и размещаем своп там, выше 4 гигов. На практике это опять же лишено всякого смысла, потому что для доступа к этой памяти нужен диапазон адресов в первых 4-х гигах, которые придется попросить из системного адресного пространства и вручную поправить таблицы страниц, но мы при этом забираем у системы виртуальные адреса, которые ей возможно нужнее, чем дополнительный своп, можно конечно каждый раз выделять/освобождать при каждом обращении к этому «свопу», но в этом еще меньше смысла.
В общем я бы сказал так, теоретически при наличии должной поддержки со стороны желаза и в каком-то особом случае, когда известно что можно безболезненно забрать у системы часть системного виртуального адресного пространства, это может и принесет какую-то пользу, но всем и каждому я бы это не рекомендовал. Это примерно как кошке пятая нога иногда может быть полезна. Поправьте меня.